dci.c 123 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


ghaddab's avatar
ghaddab committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19
   see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
ghaddab's avatar
ghaddab committed
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

/*! \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"
48
#include "SIMULATION/TOOLS/defs.h" // for taus 
49
#include "PHY/sse_intrin.h"
50

51
#include "assertions.h"
52 53 54 55

//#define DEBUG_DCI_ENCODING 1
//#define DEBUG_DCI_DECODING 1
//#define DEBUG_PHY
56

57 58
//#undef ALL_AGGREGATION

59 60
//extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3];
//extern uint16_t pcfich_reg[4];
61

62 63
uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi)
{
64

65 66 67 68
  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;
69 70 71 72 73 74 75 76 77 78 79 80 81 82

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

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

  // compute REG based on symbol
  if ((lprime == 0)||
      ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4)))
    mprime = kprime/6;
  else
    mprime = kprime>>2;

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

101 102 103
    if (frame_parms->Ncp == 1) {
      Ngroup_PHICH<<=1;
    }
104 105 106 107 108 109 110



    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]))  {
111
#ifdef DEBUG_DCI_ENCODING
112
        printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime);
113
#endif
114
        return(1);
115 116 117
      }
    }
  }
118

119 120 121
  return(0);
}

122 123
uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
{
124

125 126
  uint16_t crc16;
  //  uint8_t i;
127 128

  /*
129 130
  uint8_t crc;
  crc = ((uint16_t *)dci)[DCI_LENGTH>>4];
131 132 133
  printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH);
  crc = (crc>>(DCI_LENGTH&0xf));
  // clear crc bits
134 135 136
  ((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));
137
  // clear crc bits
138
  (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0;
139 140
  printf("extract_crc: crc %x\n",crc);
  */
141
#ifdef DEBUG_DCI_DECODING
142
  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)],
143
      dci_len&0x7);
144
#endif
145

146
  if ((dci_len&0x7) > 0) {
147 148
    ((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));
149
  } else {
150 151
    ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)];
    ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)];
152 153
  }

154
#ifdef DEBUG_DCI_DECODING
155
  LOG_I(PHY,"dci_crc =>%x\n",crc16);
156 157 158 159 160
#endif

  //  dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf));
  //  dci[(dci_len>>3)+1] = 0;
  //  dci[(dci_len>>3)+2] = 0;
161
  return((uint16_t)crc16);
162 163 164 165 166

}



167 168
static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
static uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
169

170
void dci_encoding(uint8_t *a,
171 172 173 174 175
                  uint8_t A,
                  uint16_t E,
                  uint8_t *e,
                  uint16_t rnti)
{
176 177


178 179
  uint8_t D = (A + 16);
  uint32_t RCC;
180 181

#ifdef DEBUG_DCI_ENCODING
182
  int32_t i;
183
#endif
184
  // encode dci
185 186

#ifdef DEBUG_DCI_ENCODING
187
  printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti);
188 189 190 191 192 193 194
#endif

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

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

#ifdef DEBUG_DCI_ENCODING
195 196

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

199
#endif
200

201
#ifdef DEBUG_DCI_ENCODING
202
  printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
203 204 205 206
#endif
  RCC = sub_block_interleaving_cc(D,d+96,w);

#ifdef DEBUG_DCI_ENCODING
207
  printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
208 209 210 211 212 213 214
#endif
  lte_rate_matching_cc(RCC,E,w,e);


}


215
uint8_t *generate_dci0(uint8_t *dci,
216 217 218 219 220 221
                       uint8_t *e,
                       uint8_t DCI_LENGTH,
                       uint8_t aggregation_level,
                       uint16_t rnti)
{

222 223
  uint16_t coded_bits;
  uint8_t dci_flip[8];
224 225

  if (aggregation_level>3) {
226
    printf("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
227 228 229 230 231
    return NULL;
  }

  coded_bits = 72 * (1<<aggregation_level);

232 233 234
  /*

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

260 261 262 263 264
  dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);

  return(e+coded_bits);
}

265
uint32_t Y;
266 267 268 269 270 271 272 273

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

274
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};
275 276
static mod_sym_t wtemp[2][Msymb];

277 278
void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,mod_sym_t **z, mod_sym_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
{
279 280

  mod_sym_t *wptr,*wptr2,*zptr;
281 282 283 284
  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;
285
#ifdef RM_DEBUG
286
  int32_t nulled=0;
287
#endif
288

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

293 294 295 296
  Kpi = (RCC<<5);
  ND = Kpi - Mquad;

  k=0;
297 298

  for (col=0; col<32; col++) {
299 300
    index = bitrev_cc_dci[col];

301
    for (row=0; row<RCC; row++) {
302
      //printf("col %d, index %d, row %d\n",col,index,row);
303
      if (index>=ND) {
304
        for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
305
          //printf("a %d k %d\n",a,k);
306 307 308

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

310
          //printf("wptr=%p, zptr=%p\n",wptr,zptr);
311

312 313 314 315 316
          wptr[0] = zptr[0];
          wptr[1] = zptr[1];
          wptr[2] = zptr[2];
          wptr[3] = zptr[3];
        }
317

318
        k++;
319
      }
320

321 322 323 324 325
      index+=32;
    }
  }

  // permutation
326 327 328
  for (i=0; i<Mquad; i++) {

    for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
329 330 331 332 333 334 335 336 337 338 339 340 341

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

342 343
void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi)
{
344

345 346 347
  uint32_t i, lprime;
  uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0;
  int16_t re_offset,re_offset0;
348 349 350 351 352 353 354 355 356

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

358 359 360
  case 75:
    Msymb2 = 3*Msymb/4;
    break;
361

362 363 364
  case 50:
    Msymb2 = Msymb>>1;
    break;
365

366 367 368
  case 25:
    Msymb2 = Msymb>>2;
    break;
369

370 371 372
  case 15:
    Msymb2 = Msymb*15/100;
    break;
373

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

378 379 380 381
  default:
    Msymb2 = Msymb>>2;
    break;
  }
382

383 384 385 386 387
  mprime=0;


  re_offset = 0;
  re_offset0 = 0; // counter for symbol with pilots (extracted outside!)
388 389 390

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

392
      symbol_offset = (uint32_t)frame_parms->N_RB_DL*12*lprime;
393

394 395
      tti_offset = symbol_offset + re_offset;
      tti_offset0 = symbol_offset + re_offset0;
396

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

          if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) {
            // kprime represents REG
            for (i=0; i<4; i++) {
              wbar[mprime] = llr[tti_offset+i];
429
#ifdef DEBUG_DCI_DECODING
430
              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]));
431
#endif
432 433 434 435
              mprime++;
            }
          }  // is representative
        } // no pilots case
436 437 438 439
      } // not allocated to PHICH/PCFICH

      // Stop when all REGs are copied in
      if (mprime>=Msymb2)
440
        break;
441
    } //lprime loop
442

443 444 445 446 447
    re_offset++;

  } // kprime loop
}

448
static uint16_t wtemp_rx[Msymb];
449 450
void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi)
{
451

452
  uint16_t *wptr,*zptr,*wptr2;
453

454 455 456 457
  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;
458 459 460 461 462


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

  if (!z) {
463
    printf("dci.c: pdcch_deinterleaving: FATAL z is Null\n");
464 465
    return;
  }
466

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

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

  }

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

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

  k=0;
497 498

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

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



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

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

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

529
      index+=32;
530

531 532 533
    }
  }

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

549 550 551
}


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

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

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

573
  llr128 = (int16_t*)pdcch_llr;
574 575

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

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

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

    pdcch_llr++;
    pdcch_llr8++;
  }

  return(0);
}


603
int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms,
604 605 606 607
                  int32_t **rxdataF_comp,
                  char *pdcch_llr,
                  uint8_t symbol)
{
608

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

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

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

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

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

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

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

  return(0);

}

640
//__m128i avg128P;
641 642

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

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

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

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

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

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

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

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

}

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

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

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

#endif
721
  uint8_t aarx;
722 723 724 725

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


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

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

733 734 735
#elif defined(__arm__)

#endif
736

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

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

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

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


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

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

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


805
#elif defined(__arm__)
806

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

815 816 817 818
}


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

826
  uint8_t aatx;
827

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

  if (frame_parms->nb_antennas_rx>1) {
836
    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
837 838
      //if (frame_parms->mode1_flag && (aatx>0)) break;

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

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

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

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

#endif
893 894
    }
  }
895

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


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


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

917 918

  int nushiftmod3 = frame_parms->nushift%3;
919
  uint8_t symbol_mod;
920 921 922

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

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

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

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

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

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

939
    if ((frame_parms->N_RB_DL&1) == 0)  { // even number of RBs
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

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

          //dl_ch0++;
        }

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

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

            rxF_ext[i]=rxF[i];

          }

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

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

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

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

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

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

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

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

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

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

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

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

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

      if (symbol_mod==0) {
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
        j=0;

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

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

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


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

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

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


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

1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
      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;
        }
1115 1116 1117 1118 1119
      }
    }
  }
}

1120
void pdcch_extract_rbs_dual(int32_t **rxdataF,
1121 1122 1123 1124 1125 1126 1127 1128
                            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)
{

1129

1130 1131 1132 1133
  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;
1134 1135 1136 1137
  int nushiftmod3 = frame_parms->nushift%3;

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

1138
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1139 1140 1141 1142

    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))];
1143
    } else {
1144 1145 1146
      dl_ch0     = &dl_ch_estimates[aarx][5];
      dl_ch1     = &dl_ch_estimates[2+aarx][5];
    }
1147

1148 1149 1150
    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)];

1151
    //    printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
1152 1153 1154
    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
1155

1156
    if ((frame_parms->N_RB_DL&1) == 0)  // even number of RBs
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
      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));

          /*
1171
            printf("rb %d\n",rb);
1172
            for (i=0;i<12;i++)
1173 1174
            printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
            printf("\n");
1175 1176 1177
          */
          for (i=0; i<12; i++) {
            rxF_ext[i]=rxF[i];
1178
            //      printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
1179 1180 1181 1182 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
            //  ((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;
1210
      }
1211

1212
    else {  // Odd number of RBs
1213 1214
      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {

1215
        //  printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
1216 1217 1218 1219 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

        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)
1262 1263

      if (symbol_mod > 0) {
1264 1265 1266 1267 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
        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++;
1321 1322
      }

1323 1324 1325
      for (; rb<frame_parms->N_RB_DL; rb++) {

        if (symbol_mod>0) {
1326
          //  printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
1327 1328 1329 1330 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
          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;
        }
1365 1366 1367 1368 1369 1370
      }
    }
  }
}


1371
void pdcch_channel_compensation(int32_t **rxdataF_ext,
1372 1373 1374 1375 1376 1377 1378
                                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)
{
1379

1380
  uint16_t rb;
1381
#if defined(__x86_64__) || defined(__i386__)
1382 1383
  __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
  __m128i *dl_ch128_2, *rho128;
1384 1385 1386
#elif defined(__arm__)

#endif
1387
  uint8_t aatx,aarx,pilots=0;
1388 1389 1390 1391 1392




#ifdef DEBUG_DCI_DECODING
1393
  LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol);
1394 1395 1396 1397 1398
#endif

  if (symbol==0)
    pilots=1;

1399
  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
1400 1401
    //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antennas_tx_eNB

1402
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1403

1404
#if defined(__x86_64__) || defined(__i386__)
1405 1406 1407 1408
      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];

1409 1410 1411
#elif defined(__arm__)

#endif
1412

1413 1414
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

1415
#if defined(__x86_64__) || defined(__i386__)
1416 1417 1418 1419 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
        // 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;
        }
1488 1489 1490
#elif defined(__arm__)

#endif
1491 1492 1493
      }
    }
  }
1494

1495 1496 1497

  if (rho) {

1498
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1499 1500

#if defined(__x86_64__) || defined(__i386__)
1501 1502 1503 1504
      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];

1505 1506 1507
#elif defined(__arm__)
      
#endif
1508
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
1509 1510
#if defined(__x86_64__) || defined(__i386__)

1511 1512 1513 1514 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
        // 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;

1576 1577 1578 1579
#elif defined(__arm_)


#endif
1580
      }
1581 1582 1583 1584
    }

  }

1585
#if defined(__x86_64__) || defined(__i386__)
1586 1587
  _mm_empty();
  _m_empty();
1588
#endif
1589
}
1590 1591

void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
1592 1593 1594
                         int32_t **rxdataF_comp,
                         uint8_t symbol)
{
1595

1596
  uint8_t aatx;
1597

1598
#if defined(__x86_64__) || defined(__i386__)
1599
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
1600 1601 1602
#elif defined(__arm__)
 int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1;
#endif
1603
  int32_t i;
1604 1605

  if (frame_parms->nb_antennas_rx>1) {
1606
    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
1607
#if defined(__x86_64__) || defined(__i386__)
1608 1609
      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];
1610 1611 1612 1613
#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
1614
      // MRC on each re of rb
1615
      for (i=0; i<frame_parms->N_RB_DL*3; i++) {
1616
#if defined(__x86_64__) || defined(__i386__)
1617
        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
1618 1619 1620
#elif defined(__arm__)
        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
1621 1622 1623
      }
    }
  }
1624

1625
#if defined(__x86_64__) || defined(__i386__)
1626 1627
  _mm_empty();
  _m_empty();
1628
#endif
1629 1630 1631 1632

}

void pdcch_siso(LTE_DL_FRAME_PARMS *frame_parms,
1633 1634 1635
                int32_t **rxdataF_comp,
                uint8_t l)
{
1636 1637


1638
  uint8_t rb,re,jj,ii;
1639 1640 1641 1642

  jj=0;
  ii=0;

1643 1644 1645 1646
  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

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

1647 1648 1649 1650 1651 1652 1653 1654
      rxdataF_comp[0][jj++] = rxdataF_comp[0][ii];
      ii++;
    }
  }
}


void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
1655 1656 1657
                    int32_t **rxdataF_comp,
                    uint8_t symbol)
{
1658 1659


1660 1661 1662
  int16_t *rxF0,*rxF1;
  uint8_t rb,re;
  int32_t jj=(symbol*frame_parms->N_RB_DL*12);
1663

1664 1665
  rxF0     = (int16_t*)&rxdataF_comp[0][jj];  //tx antenna 0  h0*y
  rxF1     = (int16_t*)&rxdataF_comp[2][jj];  //tx antenna 1  h1*y
1666

1667
  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
1668

1669
    for (re=0; re<12; re+=2) {
1670 1671

      // Alamouti RX combining
1672

1673 1674 1675 1676 1677
      rxF0[0] = rxF0[0] + rxF1[2];
      rxF0[1] = rxF0[1] - rxF1[3];

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

1679 1680 1681 1682 1683
      rxF0+=4;
      rxF1+=4;
    }
  }

1684

1685 1686
}

1687
int32_t avgP[4];
1688

1689
int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars,
1690 1691 1692 1693 1694 1695 1696 1697
                 LTE_UE_PDCCH **lte_ue_pdcch_vars,
                 LTE_DL_FRAME_PARMS *frame_parms,
                 uint8_t subframe,
                 uint8_t eNB_id,
                 MIMO_mode_t mimo_mode,
                 uint32_t high_speed_flag,
                 uint8_t is_secondary_ue)
{
1698

1699
  uint8_t log2_maxh,aatx,aarx;
1700
#ifdef MU_RECEIVER
1701
  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
1702
#endif
1703 1704 1705
  int32_t avgs,s;
  uint8_t n_pdcch_symbols = 3; //lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols;
  uint8_t mi = get_mi(frame_parms,subframe);
1706 1707 1708

  //  printf("In rx_pdcch, subframe %d,  eNB_id %d\n",subframe,eNB_id);

1709 1710 1711 1712 1713 1714 1715 1716 1717
  for (s=0; s<n_pdcch_symbols; s++) {
    if (is_secondary_ue == 1) {
      pdcch_extract_rbs_single(lte_ue_common_vars->rxdataF,
                               lte_ue_common_vars->dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
                               lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
                               lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                               s,
                               high_speed_flag,
                               frame_parms);
1718
#ifdef MU_RECEIVER
1719 1720 1721 1722 1723 1724 1725
      pdcch_extract_rbs_single(lte_ue_common_vars->rxdataF,
                               lte_ue_common_vars->dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
                               lte_ue_pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
                               lte_ue_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);
1726
#endif //MU_RECEIVER
1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743
    } else if (frame_parms->nb_antennas_tx_eNB>1) {
      pdcch_extract_rbs_dual(lte_ue_common_vars->rxdataF,
                             lte_ue_common_vars->dl_ch_estimates[eNB_id],
                             lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
                             lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                             s,
                             high_speed_flag,
                             frame_parms);
    } else {
      pdcch_extract_rbs_single(lte_ue_common_vars->rxdataF,
                               lte_ue_common_vars->dl_ch_estimates[eNB_id],
                               lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
                               lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                               s,
                               high_speed_flag,
                               frame_parms);
    }
1744
  }
1745

1746
  pdcch_channel_level(lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
1747 1748 1749
                      frame_parms,
                      avgP,
                      frame_parms->N_RB_DL);
1750 1751

  avgs = 0;
1752 1753 1754

  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
1755
      avgs = cmax(avgs,avgP[(aarx<<1)+aatx]);
1756

1757
  log2_maxh = (log2_approx(avgs)/2) + 6 + frame_parms->nb_antennas_rx - 1;
1758
#ifdef DEBUG_PHY
1759
  LOG_I(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs);
1760 1761 1762
#endif


1763
  for (s=0; s<n_pdcch_symbols; s++) {
1764
    pdcch_channel_compensation(lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
1765 1766 1767 1768 1769 1770
                               lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                               lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
                               (aatx>1) ? lte_ue_pdcch_vars[eNB_id]->rho : NULL,
                               frame_parms,
                               s,
                               log2_maxh); // log2_maxh+I0_shift
1771 1772 1773


#ifdef DEBUG_PHY
1774

Raymond Knopp's avatar
 
Raymond Knopp committed
1775 1776
    if (subframe==5)
      write_output("rxF_comp_d.m","rxF_c_d",&lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
1777

1778 1779 1780
#endif

#ifdef MU_RECEIVER
1781

1782 1783 1784
    if (is_secondary_ue) {
      //get MF output for interfering stream
      pdcch_channel_compensation(lte_ue_pdcch_vars[eNB_id_i]->rxdataF_ext,
1785 1786 1787 1788 1789 1790
                                 lte_ue_pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                 lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp,
                                 (aatx>1) ? lte_ue_pdcch_vars[eNB_id_i]->rho : NULL,
                                 frame_parms,
                                 s,
                                 log2_maxh); // log2_maxh+I0_shift
1791
#ifdef DEBUG_PHY
1792
      write_output("rxF_comp_i.m","rxF_c_i",&lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
1793 1794
#endif
      pdcch_dual_stream_correlation(frame_parms,
1795 1796 1797 1798 1799
                                    s,
                                    lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                                    lte_ue_pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                    lte_ue_pdcch_vars[eNB_id]->dl_ch_rho_ext,
                                    log2_maxh);
1800
    }
1801

1802
#endif //MU_RECEIVER
1803

1804 1805 1806

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

1808
      if (is_secondary_ue) {
1809 1810 1811 1812 1813 1814
        pdcch_detection_mrc_i(frame_parms,
                              lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
                              lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp,
                              lte_ue_pdcch_vars[eNB_id]->rho,
                              lte_ue_pdcch_vars[eNB_id]->dl_ch_rho_ext,
                              s);
1815
#ifdef DEBUG_PHY
1816 1817
        write_output("rxF_comp_d.m","rxF_c_d",&lte_ue_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",&lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
1818
#endif
1819
      } else
1820
#endif //MU_RECEIVER
1821 1822 1823 1824
        pdcch_detection_mrc(frame_parms,
                            lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
                            s);

1825
    }
1826 1827

    if (mimo_mode == SISO)
1828 1829 1830 1831
      pdcch_siso(frame_parms,lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,s);
    else
      pdcch_alamouti(frame_parms,lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,s);

1832

1833
#ifdef MU_RECEIVER
1834

1835 1836
    if (is_secondary_ue) {
      pdcch_qpsk_qpsk_llr(frame_parms,
1837 1838 1839 1840 1841 1842
                          lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
                          lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp,
                          lte_ue_pdcch_vars[eNB_id]->dl_ch_rho_ext,
                          lte_ue_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)
                          lte_ue_pdcch_vars[eNB_id]->llr,
                          s);
Raymond Knopp's avatar
 
Raymond Knopp committed
1843
      /*
1844
      #ifdef DEBUG_PHY
Raymond Knopp's avatar
 
Raymond Knopp committed
1845
      if (subframe==5) {
1846 1847
      write_output("llr8_seq.m","llr8",&lte_ue_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",&lte_ue_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
1848
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1849
      #endif*/
1850
    } else {
1851 1852
#endif //MU_RECEIVER
      pdcch_llr(frame_parms,
1853 1854 1855
                lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
                (char *)lte_ue_pdcch_vars[eNB_id]->llr,
                s);
Raymond Knopp's avatar
 
Raymond Knopp committed
1856
      /*#ifdef DEBUG_PHY
1857
      write_output("llr8_seq.m","llr8",&lte_ue_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
1858
      #endif*/
1859 1860
#ifdef MU_RECEIVER
    }
1861

1862 1863 1864 1865 1866 1867
#endif //MU_RECEIVER

  }

  // decode pcfich here
  n_pdcch_symbols = rx_pcfich(frame_parms,
1868 1869 1870 1871
                              subframe,
                              lte_ue_pdcch_vars[eNB_id],
                              mimo_mode);

1872 1873 1874
  if (n_pdcch_symbols>3)
    n_pdcch_symbols=1;

1875

1876
#ifdef DEBUG_DCI_DECODING
1877
  printf("[PDCCH] subframe %d n_pdcch_symbols from PCFICH =%d\n",subframe,n_pdcch_symbols);
1878

1879
  printf("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
1880 1881 1882
#endif

  pdcch_demapping(lte_ue_pdcch_vars[eNB_id]->llr,
1883 1884 1885 1886
                  lte_ue_pdcch_vars[eNB_id]->wbar,
                  frame_parms,
                  n_pdcch_symbols,
                  get_mi(frame_parms,subframe));
1887 1888

  pdcch_deinterleaving(frame_parms,
1889 1890 1891 1892 1893
                       (uint16_t*)lte_ue_pdcch_vars[eNB_id]->e_rx,
                       lte_ue_pdcch_vars[eNB_id]->wbar,
                       n_pdcch_symbols,
                       mi);

1894
  pdcch_unscrambling(frame_parms,
1895 1896 1897 1898
                     subframe,
                     lte_ue_pdcch_vars[eNB_id]->e_rx,
                     get_nCCE(n_pdcch_symbols,frame_parms,mi)*72);

1899 1900 1901 1902 1903 1904 1905
  lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols = n_pdcch_symbols;

  return(0);
}


void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
1906 1907 1908 1909
                      uint8_t subframe,
                      uint8_t *e,
                      uint32_t length)
{
1910
  int i;
1911 1912
  uint8_t reset;
  uint32_t x1, x2, s=0;
1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924

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

1926 1927 1928 1929 1930 1931 1932
    //    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,
1933 1934 1935 1936
                        uint8_t subframe,
                        int8_t* llr,
                        uint32_t length)
{
1937 1938

  int i;
1939 1940
  uint8_t reset;
  uint32_t x1, x2, s=0;
1941 1942 1943 1944 1945 1946 1947

  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++) {
1948
    if ((i&0x1f)==0) {
1949
      s = lte_gold_generic(&x1, &x2, reset);
1950
      //      printf("lte_gold[%d]=%x\n",i,s);
1951 1952
      reset = 0;
    }
1953

1954 1955
    
    //    printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1));
1956 1957
    if (((s>>(i%32))&1)==0)
      llr[i] = -llr[i];
1958
    //    printf("%d\n",llr[i]);
1959 1960 1961

  }
}
1962

1963

1964
uint8_t get_num_pdcch_symbols(uint8_t num_dci,
1965 1966 1967 1968
                              DCI_ALLOC_t *dci_alloc,
                              LTE_DL_FRAME_PARMS *frame_parms,
                              uint8_t subframe)
{
1969

1970 1971 1972
  uint16_t numCCE = 0;
  uint8_t i;
  uint8_t nCCEmin = 0;
1973 1974 1975

  // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211)
  if (frame_parms->Ncp==1) { // extended prefix
1976 1977 1978
    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
1979 1980 1981 1982 1983 1984 1985
      nCCEmin = 2;
    else {   // 10ms switching periodicity is always 3 symbols, any DL-only subframe is 3 symbols
      nCCEmin = 3;
    }
  }

  // compute numCCE
1986
  for (i=0; i<num_dci; i++) {
1987
    //     printf("dci %d => %d\n",i,dci_alloc[i].L);
1988 1989 1990 1991 1992 1993 1994
    numCCE += (1<<(dci_alloc[i].L));
  }

  //if ((9*numCCE) <= (frame_parms->N_RB_DL*2))
  if (numCCE <= get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)))
    return(cmax(1,nCCEmin));
  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 4 : 5)))
Raymond Knopp's avatar
 
Raymond Knopp committed
1995
  else if (numCCE <= get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)))
1996 1997
    return(cmax(2,nCCEmin));
  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 7 : 8)))
Raymond Knopp's avatar
 
Raymond Knopp committed
1998
  else if (numCCE <= get_nCCE(3, frame_parms, get_mi(frame_parms, subframe)))
1999
    return(cmax(3,nCCEmin));
2000
  else if (frame_parms->N_RB_DL<=10) {
2001
    if (frame_parms->Ncp == 0) { // normal CP
Raymond Knopp's avatar
 
Raymond Knopp committed
2002
      printf("numCCE %d, N_RB_DL = %d : should be returning 4 PDCCH symbols (%d,%d,%d)\n",numCCE,frame_parms->N_RB_DL,
2003 2004 2005 2006
             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)));

2007
      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 10 : 11)))
2008 2009
        return(4);
    } else { // extended CP
2010
      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 9 : 10)))
2011
        return(4);
2012 2013 2014
    }
  }

2015

2016
  LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
2017 2018
  //for (i=0;i<num_dci;i++) {
  //  printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
2019
  //}
2020 2021 2022 2023
  //exit(-1);
  return(0);
}

2024
uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
2025 2026 2027 2028 2029 2030 2031 2032
                         uint8_t num_common_dci,
                         DCI_ALLOC_t *dci_alloc,
                         uint32_t n_rnti,
                         int16_t amp,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         mod_sym_t **txdataF,
                         uint32_t subframe)
{
2033 2034 2035 2036 2037 2038 2039

  uint8_t *e_ptr,num_pdcch_symbols;
  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);
2040
  static uint8_t e[DCI_BITS_MAX];
2041
  static mod_sym_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb];
2042

2043 2044
  mod_sym_t *y[2];
  mod_sym_t *wbar[2];
2045

2046 2047 2048 2049 2050 2051 2052 2053 2054
  int nushiftmod3 = frame_parms->nushift%3;

  int Msymb2;
  int split_flag=0;

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

2056 2057 2058
  case 75:
    Msymb2 = 3*Msymb/4;
    break;
2059

2060 2061 2062
  case 50:
    Msymb2 = Msymb>>1;
    break;
2063

2064 2065 2066
  case 25:
    Msymb2 = Msymb>>2;
    break;
2067

2068 2069 2070
  case 15:
    Msymb2 = Msymb*15/100;
    break;
2071

2072 2073 2074
  case 6:
    Msymb2 = Msymb*6/100;
    break;
2075

2076 2077 2078 2079 2080 2081 2082
  default:
    Msymb2 = Msymb>>2;
    break;
  }

  num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe);
  //   printf("subframe %d in generate_dci_top num_pdcch_symbols = %d, num_dci %d\n",
2083
  //       subframe,num_pdcch_symbols,num_ue_spec_dci+num_common_dci);
2084
  generate_pcfich(num_pdcch_symbols,
2085 2086 2087 2088
                  amp,
                  frame_parms,
                  txdataF,
                  subframe);
2089 2090 2091 2092 2093 2094 2095

  wbar[0] = &wbar0[0];
  wbar[1] = &wbar1[0];
  y[0] = &yseq0[0];
  y[1] = &yseq1[0];

  // reset all bits to <NIL>, here we set <NIL> elements as 2
2096 2097 2098 2099
  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]=2;//taus()&1;
2100

2101 2102 2103 2104
  e_ptr = e;

  // 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
2105 2106
  for (L=3; L>=0; L--) {
    for (i=0; i<num_common_dci; i++) {
2107

2108
      if (dci_alloc[i].L == (uint8_t)L) {
2109

2110
#ifdef DEBUG_DCI_ENCODING
2111 2112 2113
        LOG_I(PHY,"Generating common DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_common_dci,dci_alloc[i].nCCE,dci_alloc[i].dci_length,1<<dci_alloc[i].L,
              *(unsigned int*)dci_alloc[i].dci_pdu);
        dump_dci(frame_parms,&dci_alloc[i]);
2114
#endif
2115 2116 2117 2118 2119 2120 2121 2122

        if (dci_alloc[i].nCCE>=0) {
          e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
                                e+(72*dci_alloc[i].nCCE),
                                dci_alloc[i].dci_length,
                                dci_alloc[i].L,
                                dci_alloc[i].rnti);
        }
2123 2124
      }
    }
2125 2126

    for (; i<num_ue_spec_dci + num_common_dci; i++) {
2127

2128
      if (dci_alloc[i].L == (uint8_t)L) {
2129

2130
#ifdef DEBUG_DCI_ENCODING
2131 2132 2133
        LOG_I(PHY," Generating UE (rnti %x) specific DCI %d of length %d, aggregation %d, format %d (%x)\n",dci_alloc[i].rnti,i,dci_alloc[i].dci_length,1<<dci_alloc[i].L,dci_alloc[i].format,
              dci_alloc[i].dci_pdu);
        dump_dci(frame_parms,&dci_alloc[i]);
2134
#endif
2135 2136 2137 2138 2139 2140 2141 2142

        if (dci_alloc[i].nCCE >= 0) {
          e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
                                e+(72*dci_alloc[i].nCCE),
                                dci_alloc[i].dci_length,
                                dci_alloc[i].L,
                                dci_alloc[i].rnti);
        }
2143 2144 2145 2146 2147 2148 2149
      }
    }
  }

  // Scrambling
  //  printf("pdcch scrambling\n");
  pdcch_scrambling(frame_parms,
2150 2151
                   subframe,
                   e,
2152
                   8*get_nquad(num_pdcch_symbols, frame_parms, mi));
2153 2154
  //72*get_nCCE(num_pdcch_symbols,frame_parms,mi));

2155 2156

#ifdef DEBUG_DCI_ENCODING
2157
  LOG_I(PHY," PDCCH Modulation, Msymb %d\n",Msymb);
2158
#endif
2159

2160
  // Now do modulation
2161 2162
  if (frame_parms->mode1_flag==1)
    gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
2163
  else
2164
    gain_lin_QPSK = amp/2;
2165 2166

  e_ptr = e;
2167

2168 2169
  if (frame_parms->mode1_flag) { //SISO

2170

2171
    for (i=0; i<Msymb2; i++) {
2172 2173 2174 2175
      //((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;
2176
      e_ptr++;
2177 2178 2179 2180
      //((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;
2181 2182 2183

      e_ptr++;
    }
2184
  } else { //ALAMOUTI
2185

2186

2187
    for (i=0; i<Msymb2; i+=2) {
2188 2189

#ifdef DEBUG_DCI_ENCODING
2190
      LOG_I(PHY," PDCCH Modulation (TX diversity): REG %d\n",i>>2);
2191
#endif
2192 2193 2194 2195 2196
      // first antenna position n -> x0
      ((int16_t*)&y[0][i])[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      e_ptr++;
      ((int16_t*)&y[0][i])[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      e_ptr++;
2197

2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210
      // second antenna position n -> -x1*
      ((int16_t*)&y[1][i])[0] = (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
      e_ptr++;
      ((int16_t*)&y[1][i])[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      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];

    }
2211 2212 2213 2214
  }


#ifdef DEBUG_DCI_ENCODING
2215
  LOG_I(PHY," PDCCH Interleaving\n");
2216 2217
#endif

2218
  //  printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
2219 2220 2221 2222 2223 2224 2225 2226
  // 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
2227
  //  printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]);
2228 2229
  for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) {
    for (lprime=0; lprime<num_pdcch_symbols; lprime++) {
2230

2231
      symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(lprime+(subframe*nsymb));
2232 2233


2234

2235 2236 2237 2238 2239 2240 2241 2242
      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
2243
        printf("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime);
2244
#endif
2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263
      } else {
        // Copy REG to TX buffer

        if ((lprime == 0)||
            ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4))) {
          // 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];

                if (frame_parms->nb_antennas_tx_eNB > 1)
                  txdataF[1][tti_offset+i] = wbar[1][mprime];

2264
#ifdef DEBUG_DCI_ENCODING
2265
                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]));
2266
#endif
2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282
                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];

                if (frame_parms->nb_antennas_tx_eNB > 1)
                  txdataF[1][tti_offset+i] = wbar[1][mprime];

2283
#ifdef DEBUG_DCI_ENCODING
2284
                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]));
2285
#endif
2286 2287 2288 2289 2290 2291 2292 2293
                mprime++;
              }
            } else {
              txdataF[0][tti_offset+0] = wbar[0][mprime];

              if (frame_parms->nb_antennas_tx_eNB > 1)
                txdataF[1][tti_offset+0] = wbar[1][mprime];

2294
#ifdef DEBUG_DCI_ENCODING
2295
              LOG_I(PHY," 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]));
2296
#endif
2297 2298 2299 2300 2301 2302
              mprime++;
              txdataF[0][tti_offset+1] = wbar[0][mprime];

              if (frame_parms->nb_antennas_tx_eNB > 1)
                txdataF[1][tti_offset+1] = wbar[1][mprime];

2303
#ifdef DEBUG_DCI_ENCODING
2304
              LOG_I(PHY," 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]));
2305
#endif
2306 2307 2308 2309 2310 2311
              mprime++;
              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];

              if (frame_parms->nb_antennas_tx_eNB > 1)
                txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime];

2312
#ifdef DEBUG_DCI_ENCODING
2313 2314
              LOG_I(PHY," 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],
                    *(1+(short*)&wbar[0][mprime]));
2315
#endif
2316 2317 2318 2319 2320 2321
              mprime++;
              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime];

              if (frame_parms->nb_antennas_tx_eNB > 1)
                txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime];

2322
#ifdef DEBUG_DCI_ENCODING
2323 2324
              LOG_I(PHY," 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],
                    *(1+(short*)&wbar[0][mprime]));
2325
#endif
2326 2327 2328 2329 2330
              mprime++;

            }
          }
        }
2331

2332 2333
        if (mprime>=Msymb2)
          return(num_pdcch_symbols);
2334
      } // check_phich_reg
2335

2336
    } //lprime loop
2337

2338
    re_offset++;
2339

2340 2341 2342
    if (re_offset == (frame_parms->ofdm_symbol_size))
      re_offset = 1;
  } // kprime loop
2343

2344 2345 2346 2347
  return(num_pdcch_symbols);
}

#ifdef PHY_ABSTRACTION
2348
uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
2349 2350 2351 2352 2353
                              uint8_t num_ue_spec_dci,
                              uint8_t num_common_dci,
                              DCI_ALLOC_t *dci_alloc,
                              uint8_t subframe)
{
2354
  int n_dci, n_dci_dl;
2355
  uint8_t ue_id;
2356
  LTE_eNB_DLSCH_t *dlsch_eNB;
2357
  uint8_t num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,
2358 2359 2360
                              dci_alloc,
                              &phy_vars_eNB->lte_frame_parms,
                              subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
2361
  eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.cfi=num_pdcch_symbols;
2362 2363 2364 2365

  memcpy(phy_vars_eNB->dci_alloc[subframe&1],dci_alloc,sizeof(DCI_ALLOC_t)*(num_ue_spec_dci+num_common_dci));
  phy_vars_eNB->num_ue_spec_dci[subframe&1]=num_ue_spec_dci;
  phy_vars_eNB->num_common_dci[subframe&1]=num_common_dci;
Raymond Knopp's avatar
 
Raymond Knopp committed
2366 2367
  eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci = num_ue_spec_dci;
  eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci = num_common_dci;
2368

2369 2370 2371
  LOG_D(PHY,"[eNB %d][DCI][EMUL] CC id %d:  num spec dci %d num comm dci %d num PMCH %d \n",
        phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, num_ue_spec_dci,num_common_dci,
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch);
2372

Raymond Knopp's avatar
 
Raymond Knopp committed
2373 2374
  if (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.pmch_flag == 1 )
    n_dci_dl = eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch;
2375
  else
2376 2377
    n_dci_dl = 0;

2378
  for (n_dci =0 ;
Raymond Knopp's avatar
 
Raymond Knopp committed
2379
       n_dci < (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci+ eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci);
2380
       n_dci++) {
2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410

    if (dci_alloc[n_dci].format > 0) { // exclude the uplink dci

      if (dci_alloc[n_dci].rnti == SI_RNTI) {
        dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_eNB_SI;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 0;//SI;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3;
        LOG_D(PHY,"[DCI][EMUL]SI tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
              eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
      } else if (dci_alloc[n_dci_dl].ra_flag == 1) {
        dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_eNB_ra;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 1;//RA;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3;
        LOG_D(PHY,"[DCI][EMUL] RA  tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
              eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
      } else {
        ue_id = find_ue(dci_alloc[n_dci_dl].rnti,PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]);
        DevAssert( ue_id != (uint8_t)-1 );
        dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_eNB[ue_id][0];

        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 2;//TB0;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = dlsch_eNB->current_harq_pid;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].ue_id[n_dci_dl] = ue_id;
        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[dlsch_eNB->current_harq_pid]->TBS>>3;
        LOG_D(PHY,"[DCI][EMUL] TB1 tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
              eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
        // check for TB1 later

2411 2412
      }
    }
2413

2414 2415
    n_dci_dl++;
  }
2416

Raymond Knopp's avatar
 
Raymond Knopp committed
2417
  memcpy((void *)&eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dci_alloc,
2418 2419
         (void *)dci_alloc,
         n_dci*sizeof(DCI_ALLOC_t));
2420 2421 2422

  return(num_pdcch_symbols);
}
2423 2424
#endif

2425

2426
void dci_decoding(uint8_t DCI_LENGTH,
2427 2428 2429 2430
                  uint8_t aggregation_level,
                  int8_t *e,
                  uint8_t *decoded_output)
{
2431 2432 2433 2434

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

2435
  uint16_t RCC;
2436

2437 2438
  uint16_t D=(DCI_LENGTH+16+64);
  uint16_t coded_bits;
2439
#ifdef DEBUG_DCI_DECODING
2440
  int32_t i;
2441
#endif
2442

2443
  if (aggregation_level>3) {
2444
    LOG_I(PHY," dci.c: dci_decoding FATAL, illegal aggregation_level %d\n",aggregation_level);
2445 2446 2447 2448 2449 2450
    return;
  }

  coded_bits = 72 * (1<<aggregation_level);

#ifdef DEBUG_DCI_DECODING
2451
  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);
2452
#endif
2453

2454 2455 2456
  // now do decoding
  memset((void*)dummy_w_rx,0,3*D);
  RCC = generate_dummy_w_cc(DCI_LENGTH+16,
2457 2458
                            dummy_w_rx);

2459 2460 2461


#ifdef DEBUG_DCI_DECODING
2462
  LOG_I(PHY," Doing DCI Rate Matching RCC %d, w %p\n",RCC,w);
2463 2464 2465
#endif

  lte_rate_matching_cc_rx(RCC,coded_bits,w_rx,dummy_w_rx,e);
2466 2467 2468 2469 2470

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

2471
#ifdef DEBUG_DCI_DECODING
2472 2473

  for (i=0; i<16+DCI_LENGTH; i++)
2474
    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)));
2475 2476

#endif
2477
  memset(decoded_output,0,2+((16+DCI_LENGTH)>>3));
2478

2479
#ifdef DEBUG_DCI_DECODING
2480
  printf("Before Viterbi\n");
2481

2482
  for (i=0; i<16+DCI_LENGTH; i++)
2483
    printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
2484 2485

#endif
2486
  //debug_printf("Doing DCI Viterbi \n");
2487
  phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH);
2488
  //debug_printf("Done DCI Viterbi \n");
2489 2490 2491
}


2492
static uint8_t dci_decoded_output[(MAX_DCI_SIZE_BITS+64)/8];
2493

2494 2495
uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi)
{
2496 2497 2498
  return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9);
}

2499 2500
uint16_t get_nquad(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi)
{
2501

2502
  uint16_t Nreg=0;
2503
  uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
2504 2505 2506 2507 2508 2509 2510

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

2512 2513 2514 2515 2516 2517 2518
  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;
2519

2520 2521 2522
    case 25:
      Nreg=50+(num_pdcch_symbols-1)*75;
      break;
2523

2524 2525 2526
    case 50:
      Nreg=100+(num_pdcch_symbols-1)*150;
      break;
2527

2528 2529 2530
    case 100:
      Nreg=200+(num_pdcch_symbols-1)*300;
      break;
2531

2532 2533 2534
    default:
      return(0);
    }
2535

2536 2537 2538 2539
  //   printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH));
  return(Nreg - 4 - (3*Ngroup_PHICH));
}

2540 2541
uint16_t get_nCCE_max(uint8_t Mod_id,uint8_t CC_id)
{
2542 2543

  // check for eNB only !
Raymond Knopp's avatar
 
Raymond Knopp committed
2544
  return(get_nCCE(3,&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,1)); // 5, 15,21
2545 2546
}

2547 2548 2549
void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,
			     int do_common,
			     uint8_t subframe,
2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569
                             DCI_ALLOC_t *dci_alloc,
                             int16_t eNB_id,
                             LTE_DL_FRAME_PARMS *frame_parms,
                             uint8_t mi,
                             uint16_t si_rnti,
                             uint16_t ra_rnti,
                             uint8_t L,
                             uint8_t format_si,
                             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)
{

2570 2571
  uint16_t crc,CCEind,nCCE;
  uint32_t *CCEmap=NULL,CCEmap_mask=0;
2572
  int L2=(1<<L);
2573
  unsigned int Yk,nb_candidates = 0,i,m;
2574 2575 2576
  unsigned int CCEmap_cand;

  nCCE = get_nCCE(lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi);
2577

2578
  if (nCCE > get_nCCE(3,frame_parms,1))
2579 2580
    return;

2581 2582 2583 2584 2585 2586
  if (nCCE<L2)
    return;

  if (do_common == 1) {
    nb_candidates = (L2==4) ? 4 : 2;
    Yk=0;
2587
  } else {
2588 2589 2590 2591 2592
    // 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)lte_ue_pdcch_vars[eNB_id]->crnti;

2593
    for (i=0; i<=subframe; i++)
2594 2595 2596 2597 2598 2599 2600 2601 2602
      Yk = (Yk*39827)%65537;

    Yk = Yk % (nCCE/L2);

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

2604 2605 2606 2607
    case 4:
    case 8:
      nb_candidates = 2;
      break;
2608

2609 2610 2611
    default:
      DevParam(L2, do_common, eNB_id);
      break;
2612
    }
2613
  }
2614

2615 2616 2617 2618 2619 2620 2621
  /*  for (CCEind=0;
       CCEind<nCCE2;
       CCEind+=(1<<L)) {*/

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

2622
  for (m=0; m<nb_candidates; m++) {
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633

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

    if (CCEind<32)
      CCEmap = CCEmap0;
    else if (CCEind<64)
      CCEmap = CCEmap1;
    else if (CCEind<96)
      CCEmap = CCEmap2;
    else {
      LOG_E(PHY,"Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind,Yk,m,nCCE,L2);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2634
      mac_xface->macphy_exit("Illegal CCEind\n");
2635
      return; // not reached
2636
    }
2637

2638 2639 2640 2641
    switch (L2) {
    case 1:
      CCEmap_mask = (1<<(CCEind&0x1f));
      break;
2642

2643 2644 2645
    case 2:
      CCEmap_mask = (3<<(CCEind&0x1f));
      break;
2646

2647 2648 2649
    case 4:
      CCEmap_mask = (0xf<<(CCEind&0x1f));
      break;
2650

2651 2652 2653
    case 8:
      CCEmap_mask = (0xff<<(CCEind&0x1f));
      break;
2654 2655 2656 2657 2658

    default:
      LOG_E( PHY, "Illegal L2 value %d\n", L2 );
      mac_xface->macphy_exit( "Illegal L2\n" );
      return; // not reached
2659 2660
    }

2661
    CCEmap_cand = (*CCEmap)&CCEmap_mask;
2662 2663

    // CCE is not allocated yet
2664 2665 2666

    if (CCEmap_cand == 0) {
#ifdef DEBUG_DCI_DECODING
2667 2668 2669

      if (do_common == 1)
        LOG_I(PHY,"[DCI search - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
2670
      else
2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683
        LOG_I(PHY,"[DCI search - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);

#endif

      dci_decoding(sizeof_bits,
                   L,
                   &lte_ue_pdcch_vars[eNB_id]->e_rx[CCEind*72],
                   dci_decoded_output);
      /*
        for (i=0;i<3+(sizeof_bits>>3);i++)
        printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]);
      */
      crc = (crc16(dci_decoded_output,sizeof_bits)>>16) ^ extract_crc(dci_decoded_output,sizeof_bits);
2684
#ifdef DEBUG_DCI_DECODING
2685
      printf("crc =>%x\n",crc);
2686
#endif
2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700

      if (((L>1) && ((crc == si_rnti)||
                     (crc == ra_rnti)))||
          (crc == lte_ue_pdcch_vars[eNB_id]->crnti))   {
        dci_alloc[*dci_cnt].dci_length = sizeof_bits;
        dci_alloc[*dci_cnt].rnti       = crc;
        dci_alloc[*dci_cnt].L          = L;
        dci_alloc[*dci_cnt].nCCE       = CCEind;

        if (sizeof_bytes<=4) {
          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[0];
          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[1];
          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[2];
          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[3];
2701
#ifdef DEBUG_DCI_DECODING
2702
          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3]);
2703
#endif
2704 2705 2706 2707 2708 2709 2710 2711 2712
        } else {
          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[0];
          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[1];
          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[2];
          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[3];
          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[4];
          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[5];
          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[6];
          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[7];
2713
#ifdef DEBUG_DCI_DECODING
2714
          printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
2715 2716
              dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3],
              dci_decoded_output[4],dci_decoded_output[5],dci_decoded_output[6],dci_decoded_output[7]);
2717
#endif
2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773
        }

        if (crc==si_rnti) {
          dci_alloc[*dci_cnt].format     = format_si;
          *dci_cnt = *dci_cnt+1;
        } else if (crc==ra_rnti) {
          dci_alloc[*dci_cnt].format     = format_ra;
          // store first nCCE of group for PUCCH transmission of ACK/NAK
          lte_ue_pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
          *dci_cnt = *dci_cnt+1;
        } else if (crc==lte_ue_pdcch_vars[eNB_id]->crnti) {

          if ((format_c == format0)&&((dci_decoded_output[0]&0x80)==0)) {// check if pdu is format 0 or 1A
            if (*format0_found == 0) {
              dci_alloc[*dci_cnt].format     = format0;
              *format0_found = 1;
              *dci_cnt = *dci_cnt+1;
              lte_ue_pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
            }
          } else if (format_c == format0) { // this is a format 1A DCI
            dci_alloc[*dci_cnt].format     = format1A;
            *dci_cnt = *dci_cnt+1;
            lte_ue_pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
          } 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;
              lte_ue_pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
            }
          }
        }

        //  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:
          *CCEmap|=(0x03<<(CCEind&0x1f));
          break;

        case 4:
          *CCEmap|=(0x0f<<(CCEind&0x1f));
          break;

        case 8:
          *CCEmap|=(0xff<<(CCEind&0x1f));
          break;
        }

2774
#ifdef DEBUG_DCI_DECODING
2775 2776 2777 2778
        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x)\n",
              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap);
        dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);

2779
#endif
2780 2781 2782 2783 2784

        //  if (crc==lte_ue_pdcch_vars[eNB_id]->crnti)
        //    return;
      } // rnti match
    }  // CCEmap_cand == 0
2785 2786 2787
  } // candidate loop
}

2788
uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
2789 2790 2791 2792 2793 2794
                                DCI_ALLOC_t *dci_alloc,
                                int do_common,
                                int16_t eNB_id,
                                uint8_t subframe)
{

2795 2796
  uint8_t  dci_cnt=0,old_dci_cnt=0;
  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
2797 2798
  LTE_UE_PDCCH **lte_ue_pdcch_vars = phy_vars_ue->lte_ue_pdcch_vars;
  LTE_DL_FRAME_PARMS *frame_parms  = &phy_vars_ue->lte_frame_parms;
2799 2800 2801 2802 2803
  uint8_t mi = get_mi(&phy_vars_ue->lte_frame_parms,subframe);
  uint16_t ra_rnti=99;
  uint8_t format0_found=0,format_c_found=0;
  uint8_t tmode = phy_vars_ue->transmission_mode[eNB_id];
  uint8_t frame_type = frame_parms->frame_type;
2804
  uint8_t format1A_size_bits=0,format1A_size_bytes=0;
2805
  uint8_t format1C_size_bits=0,format1C_size_bytes=0;
2806 2807 2808 2809
  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;
2810 2811 2812 2813 2814 2815

  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);
2816 2817
      format1C_size_bits  = sizeof_DCI1C_1_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
2818 2819 2820 2821
      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);
2822

2823
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2824 2825 2826 2827 2828 2829 2830 2831 2832
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2833
      }
2834
    } else {
2835 2836
      format1A_size_bits  = sizeof_DCI1A_1_5MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
2837 2838
      format1C_size_bits  = sizeof_DCI1C_1_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
2839 2840 2841 2842
      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);
2843

2844
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2845 2846 2847 2848 2849 2850 2851 2852 2853
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2854
      }
2855
    }
2856

2857
    break;
2858

2859
  case 25:
Raymond Knopp's avatar
 
Raymond Knopp committed
2860
  default:
2861 2862 2863
    if (frame_type == TDD) {
      format1A_size_bits  = sizeof_DCI1A_5MHz_TDD_1_6_t;
      format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
2864 2865
      format1C_size_bits  = sizeof_DCI1C_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_5MHz_t);
2866 2867 2868 2869
      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);
2870

2871
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2872 2873 2874 2875 2876 2877 2878 2879 2880
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2881
      }
2882
    } else {
2883 2884
      format1A_size_bits  = sizeof_DCI1A_5MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t);
2885 2886
      format1C_size_bits  = sizeof_DCI1C_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_5MHz_t);
2887 2888 2889 2890
      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);
2891

2892
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2893 2894 2895 2896 2897 2898 2899 2900 2901
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2902
      }
2903
    }
2904

2905
    break;
2906

2907 2908 2909 2910
  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
2911 2912
      format1C_size_bits  = sizeof_DCI1C_10MHz_t;
      format1C_size_bytes = sizeof(DCI1C_10MHz_t);
2913 2914 2915 2916
      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);
2917

2918
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2919 2920 2921 2922 2923 2924 2925 2926 2927
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2928
      }
2929
    } else {
2930 2931
      format1A_size_bits  = sizeof_DCI1A_10MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t);
2932 2933
      format1C_size_bits  = sizeof_DCI1C_10MHz_t;
      format1C_size_bytes = sizeof(DCI1C_10MHz_t);
2934 2935 2936 2937
      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);
2938

2939
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2940 2941 2942 2943 2944 2945 2946 2947 2948
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2949
      }
2950
    }
2951

2952 2953 2954 2955 2956 2957
    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);
2958 2959
      format1C_size_bits  = sizeof_DCI1C_20MHz_t;
      format1C_size_bytes = sizeof(DCI1C_20MHz_t);
2960 2961 2962 2963
      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);
2964

2965
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2966 2967 2968 2969 2970 2971 2972 2973 2974
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2975
      }
2976
    } else {
2977 2978
      format1A_size_bits  = sizeof_DCI1A_20MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t);
2979 2980
      format1C_size_bits  = sizeof_DCI1C_20MHz_t;
      format1C_size_bytes = sizeof(DCI1C_20MHz_t);
2981 2982 2983 2984
      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);
2985

2986
      if (frame_parms->nb_antennas_tx_eNB == 2) {
2987 2988 2989 2990 2991 2992 2993 2994 2995
        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);
      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
        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
2996
      }
2997
    }
2998

2999 3000 3001
    break;
  }

3002
  if (do_common == 1) {
3003 3004 3005
#ifdef DEBUG_DCI_DECODING
    printf("[DCI search] doing common search/format0 aggregation 4\n");
#endif
3006

3007 3008
    if (phy_vars_ue->prach_resources[eNB_id])
      ra_rnti = phy_vars_ue->prach_resources[eNB_id]->ra_RNTI;
3009

3010
    // First check common search spaces at aggregation 4 (SI_RNTI and RA_RNTI format 0/1A),
3011 3012
    // and UE_SPEC format0 (PUSCH) too while we're at it
    dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            2,
                            format1A,
                            format1A,
                            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)))
3034
      return(dci_cnt);
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
    // Now check common search spaces at aggregation 4 (SI_RNTI and RA_RNTI and C-RNTI format 1C),
    // and UE_SPEC format0 (PUSCH) too while we're at it
    dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            2,
                            format1C,
                            format1C,
                            format1C,
                            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);

3062
    // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI format 1A),
3063 3064 3065 3066 3067 3068
    // 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
    dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            3,
                            format1A,
                            format1A,
                            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)))
3090
      return(dci_cnt);
3091

3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112
    // 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
    dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            3,
                            format1C,
                            format1C,
                            format1C,
                            format1C_size_bits,
                            format1C_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3113 3114 3115 3116 3117 3118 3119 3120 3121 3122
    //#endif

  }

  if (phy_vars_ue->UE_mode[eNB_id] <= PRACH)
    return(dci_cnt);

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

3123
  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
3124 3125
  //  printf("[DCI search] Format 0/1A aggregation 8\n");
  dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146
                          subframe,
                          dci_alloc,
                          eNB_id,
                          frame_parms,
                          mi,
                          SI_RNTI,
                          ra_rnti,
                          3,
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

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

3150
  //  printf("[DCI search] Format 0 aggregation 4\n");
3151
  // Now check UE_SPEC format 0 search spaces at aggregation 4
3152
  dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173
                          subframe,
                          dci_alloc,
                          eNB_id,
                          frame_parms,
                          mi,
                          SI_RNTI,
                          ra_rnti,
                          2,
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

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

3177
  if ((CCEmap0==0xffff)||
3178 3179
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);
3180

3181
  //  printf("[DCI search] Format 0 aggregation 2\n");
3182
  // Now check UE_SPEC format 0 search spaces at aggregation 2
3183
  dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204
                          subframe,
                          dci_alloc,
                          eNB_id,
                          frame_parms,
                          mi,
                          SI_RNTI,
                          ra_rnti,
                          1,
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
3205 3206 3207 3208
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);

  //  printf("[DCI search] Format 0 aggregation 4\n");
3209
  // Now check UE_SPEC format 0 search spaces at aggregation 1
3210
  dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231
                          subframe,
                          dci_alloc,
                          eNB_id,
                          frame_parms,
                          mi,
                          SI_RNTI,
                          ra_rnti,
                          0,
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
3232 3233 3234 3235 3236 3237 3238 3239
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);




  // These are for CRNTI based on transmission mode
  if (tmode < 3) {
3240
    // Now check UE_SPEC format 1 search spaces at aggregation 1
3241 3242
    old_dci_cnt=dci_cnt;
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,subframe,
3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            0,
                            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))
3264
      return(dci_cnt);
3265

3266 3267
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3268 3269

    // Now check UE_SPEC format 1 search spaces at aggregation 2
3270 3271
    old_dci_cnt=dci_cnt;
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,subframe,
3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            1,
                            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))
3294
      return(dci_cnt);
3295

3296
    if (dci_cnt>old_dci_cnt)
3297
      return(dci_cnt);
3298

3299
    // Now check UE_SPEC format 1 search spaces at aggregation 4
3300 3301
    old_dci_cnt=dci_cnt;
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,subframe,
3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            2,
                            format1A,
                            format1A,
                            format1,
                            format1_size_bits,
                            format1_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

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

3325 3326 3327 3328 3329 3330 3331
    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;
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,subframe,
3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            3,
                            format1A,
                            format1A,
                            format1,
                            format1_size_bits,
                            format1_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

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

3355 3356
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3357 3358 3359

    //#endif //ALL_AGGREGATION
  } else if (tmode == 3) {
3360 3361


3362
    // Now check UE_SPEC format 2A_2A search spaces at aggregation 1
3363
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            0,
                            format1A,
                            format1A,
                            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)))
3386
      return(dci_cnt);
3387

3388 3389 3390
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3391
    // Now check UE_SPEC format 2 search spaces at aggregation 2
3392
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            1,
                            format1A,
                            format1A,
                            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)))
3415
      return(dci_cnt);
3416

3417 3418 3419
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3420
    // Now check UE_SPEC format 2_2A search spaces at aggregation 4
3421
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            2,
                            format1A,
                            format1A,
                            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)))
3444
      return(dci_cnt);
3445

3446 3447 3448 3449
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

    //#ifdef ALL_AGGREGATION
3450
    // Now check UE_SPEC format 2_2A search spaces at aggregation 8
3451
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            3,
                            format1A,
                            format1A,
                            format2A,
                            format2A_size_bits,
                            format2A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3471
    //#endif
3472
  } else if (tmode == 4) {
3473

3474
    // Now check UE_SPEC format 2_2A search spaces at aggregation 1
3475
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            0,
                            format1A,
                            format1A,
                            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)))
3498
      return(dci_cnt);
3499

3500 3501 3502
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3503
    // Now check UE_SPEC format 2 search spaces at aggregation 2
3504
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            1,
                            format1A,
                            format1A,
                            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)))
3527
      return(dci_cnt);
3528

3529 3530 3531
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3532
    // Now check UE_SPEC format 2_2A search spaces at aggregation 4
3533
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            2,
                            format1A,
                            format1A,
                            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)))
3556
      return(dci_cnt);
3557

3558 3559 3560 3561
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

    //#ifdef ALL_AGGREGATION
3562
    // Now check UE_SPEC format 2_2A search spaces at aggregation 8
3563
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            3,
                            format1A,
                            format1A,
                            format2,
                            format2_size_bits,
                            format2_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3583
    //#endif
3584
  } else if (tmode >=5) { // This is MU-MIMO
3585

3586
    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1
3587
#ifdef DEBUG_DCI_DECODING
3588
    LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n");
3589
#endif
3590
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            0,
                            format1A,
                            format1A,
                            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)))
3614
      return(dci_cnt);
3615

3616 3617
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3618 3619

    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2
3620
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            1,
                            format1A,
                            format1A,
                            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);
3644

3645 3646
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3647

3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672
    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            2,
                            format1A,
                            format1A,
                            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);
3673

3674 3675
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3676

3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710
    //#ifdef ALL_AGGREGATION

    // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8
    dci_decoding_procedure0(lte_ue_pdcch_vars,0,
                            subframe,
                            dci_alloc,
                            eNB_id,
                            frame_parms,
                            mi,
                            SI_RNTI,
                            ra_rnti,
                            3,
                            format1A,
                            format1A,
                            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

  }
3711 3712 3713 3714 3715

  return(dci_cnt);
}

#ifdef PHY_ABSTRACTION
3716
uint16_t dci_decoding_procedure_emul(LTE_UE_PDCCH **lte_ue_pdcch_vars,
3717 3718 3719 3720 3721 3722 3723
                                     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)
{

3724
  uint8_t  dci_cnt=0,i;
3725

3726 3727 3728 3729
  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);

3730
  for (i=num_common_dci; i<(num_ue_spec_dci+num_common_dci); i++) {
3731
    LOG_D(PHY,"[DCI][EMUL] Checking dci %d => %x format %d (bit 0 %d)\n",i,lte_ue_pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format,
3732 3733
          dci_alloc_tx[i].dci_pdu[0]&0x80);

3734 3735 3736 3737 3738 3739 3740 3741 3742 3743
    if (dci_alloc_tx[i].rnti == lte_ue_pdcch_vars[eNB_id]->crnti) {
      memcpy(dci_alloc_rx+dci_cnt,dci_alloc_tx+i,sizeof(DCI_ALLOC_t));
      dci_cnt++;
    }
  }


  return(dci_cnt);
}
#endif