dci_tools.c 326 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

/*! \file PHY/LTE_TRANSPORT/dci_tools.c
31
 * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler.
32 33 34 35 36 37 38 39 40 41 42 43 44 45
 * \author R. Knopp
 * \date 2011
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr
 * \note
 * \warning
 */
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#ifdef DEBUG_DCI_TOOLS
#include "PHY/vars.h"
#endif
winckel's avatar
winckel committed
46
#include "assertions.h"
47
//#define DEBUG_HARQ
48 49 50

//#define DEBUG_DCI

51 52 53
uint32_t localRIV2alloc_LUT6[32];
uint32_t distRIV2alloc_even_LUT6[32];
uint32_t distRIV2alloc_odd_LUT6[32];
54 55 56 57
uint16_t RIV2nb_rb_LUT6[32];
uint16_t RIV2first_rb_LUT6[32];
uint16_t RIV_max6=0;

58 59 60
uint32_t localRIV2alloc_LUT25[512];
uint32_t distRIV2alloc_even_LUT25[512];
uint32_t distRIV2alloc_odd_LUT25[512];
61 62 63 64 65
uint16_t RIV2nb_rb_LUT25[512];
uint16_t RIV2first_rb_LUT25[512];
uint16_t RIV_max25=0;


66 67 68 69 70 71 72 73 74 75
uint32_t localRIV2alloc_LUT50_0[1600];
uint32_t localRIV2alloc_LUT50_1[1600];
uint32_t distRIV2alloc_gap0_even_LUT50_0[1600];
uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600];
uint32_t distRIV2alloc_gap0_even_LUT50_1[1600];
uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600];
uint32_t distRIV2alloc_gap1_even_LUT50_0[1600];
uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600];
uint32_t distRIV2alloc_gap1_even_LUT50_1[1600];
uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600];
76 77 78 79
uint16_t RIV2nb_rb_LUT50[1600];
uint16_t RIV2first_rb_LUT50[1600];
uint16_t RIV_max50=0;

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
uint32_t localRIV2alloc_LUT100_0[6000];
uint32_t localRIV2alloc_LUT100_1[6000];
uint32_t localRIV2alloc_LUT100_2[6000];
uint32_t localRIV2alloc_LUT100_3[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_0[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_1[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_2[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_3[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_0[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_1[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_2[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_3[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000];
100 101 102 103 104 105 106 107 108
uint16_t RIV2nb_rb_LUT100[6000];
uint16_t RIV2first_rb_LUT100[6000];
uint16_t RIV_max100=0;


extern uint32_t current_dlsch_cqi;

// Table 8.6.3-3 36.213
uint16_t beta_cqi[16] = {0,   //reserved
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
                         0,   //reserved
                         9,   //1.125
                         10,  //1.250
                         11,  //1.375
                         13,  //1.625
                         14,  //1.750
                         16,  //2.000
                         18,  //2.250
                         20,  //2.500
                         23,  //2.875
                         25,  //3.125
                         28,  //3.500
                         32,  //4.000
                         40,  //5.000
                         50
                        }; //6.250
125 126 127

// Table 8.6.3-2 36.213
uint16_t beta_ri[16] = {10,   //1.250
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
                        13,   //1.625
                        16,   //2.000
                        20,   //2.500
                        25,   //3.125
                        32,   //4.000
                        40,   //5.000
                        50,   //6.250
                        64,   //8.000
                        80,   //10.000
                        101,  //12.625
                        127,  //15.875
                        160,  //20.000
                        0,    //reserved
                        0,    //reserved
                        0
                       };   //reserved
144 145 146

// Table 8.6.3-2 36.213
uint16_t beta_ack[16] = {16,  //2.000
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
                         20,  //2.500
                         25,  //3.125
                         32,  //4.000
                         40,  //5.000
                         50,  //6.250
                         64,  //8.000
                         80,  //10.000
                         101, //12.625
                         127, //15.875
                         160, //20.000
                         248, //31.000
                         400, //50.000
                         640, //80.000
                         808
                        };//126.00
162 163 164 165 166

int8_t delta_PUSCH_abs[4] = {-4,-1,1,4};
int8_t delta_PUSCH_acc[4] = {-1,0,1,3};

int8_t *delta_PUCCH_lut = delta_PUSCH_acc;
167 168 169

void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2)
{
170 171

  uint32_t i,shift,subset;
172 173 174 175
  rb_alloc2[0] = 0;
  rb_alloc2[1] = 0;
  rb_alloc2[2] = 0;
  rb_alloc2[3] = 0;
176 177 178 179 180 181 182 183 184 185 186

  //  printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc);

  switch (N_RB_DL) {

  case 6:
    rb_alloc2[0] = rb_alloc&0x3f;
    break;

  case 25:
    if (ra_header == 0) {// Type 0 Allocation
187 188 189 190 191 192

      for (i=12; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          rb_alloc2[0] |= (3<<((2*(12-i))));

        //      printf("rb_alloc2 (type 0) %x\n",rb_alloc2);
193
      }
194

195
      if ((rb_alloc&1) != 0)
196 197
        rb_alloc2[0] |= (1<<24);
    } else {
198 199
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;
200 201 202 203 204 205

      for (i=0; i<11; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          rb_alloc2[0] |= (1<<(2*i));

        //printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
206
      }
207

208
      if ((shift == 0) && (subset == 1))
209
        rb_alloc2[0]<<=1;
210
      else if ((shift == 1) && (subset == 0))
211
        rb_alloc2[0]<<=4;
212
      else if ((shift == 1) && (subset == 1))
213
        rb_alloc2[0]<<=3;
214
    }
215

216
    break;
217

218 219 220 221 222 223 224
  case 50:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=16; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32));
      }
225

226
      /*
227 228 229 230
      for (i=1;i<=16;i++) {
        if ((rb_alloc&(1<<(16-i))) != 0)
      rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
      }
231
      */
232
      // bit mask across
233 234
      if ((rb_alloc2[0]>>31)==1)
        rb_alloc2[1] |= 1;
235

236
      if ((rb_alloc&1) != 0)
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
        rb_alloc2[1] |= (3<<16);

      /*
        for (i=0;i<16;i++) {
        if (((rb_alloc>>(16-i))&1) != 0)
        rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
        if ((i==10)&&((rb_alloc&(1<<6))!=0))
        rb_alloc2[1] = 1;
        //  printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);

        }
        // fill in 2 from last bit instead of 3
        if ((rb_alloc&1) != 0)
        rb_alloc2[1] |= (3<<i);
        //    printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);
        */
253
      //      printf("rb_alloc[1]=%x,rb_alloc[0]=%x\n",rb_alloc2[1],rb_alloc2[0]);
254
    } else {
255 256
      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=50\n");
      //      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
257
      /*
258 259 260 261 262 263 264 265 266 267 268 269 270
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;
      for (i=0;i<11;i++) {
      if ((rb_alloc&(1<<(i+2))) != 0)
      rb_alloc2 |= (1<<(2*i));
      //      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
      }
      if ((shift == 0) && (subset == 1))
      rb_alloc2<<=1;
      else if ((shift == 1) && (subset == 0))
      rb_alloc2<<=4;
      else if ((shift == 1) && (subset == 1))
      rb_alloc2<<=3;
271 272
      */
    }
273

274 275 276 277
    break;

  case 100:
    if (ra_header == 0) {// Type 0 Allocation
278 279 280 281 282
      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(24-i))) != 0)
          rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32));

        //  printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i));
283
      }
284
    } else {
285
      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=100\n");
286
      //      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
287
      /*
288 289 290 291 292 293 294 295 296 297 298 299 300
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;
      for (i=0;i<11;i++) {
      if ((rb_alloc&(1<<(i+2))) != 0)
      rb_alloc2 |= (1<<(2*i));
      //      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
      }
      if ((shift == 0) && (subset == 1))
      rb_alloc2<<=1;
      else if ((shift == 1) && (subset == 0))
      rb_alloc2<<=4;
      else if ((shift == 1) && (subset == 1))
      rb_alloc2<<=3;
301 302
      */
    }
303

304 305 306
    break;

  default:
winckel's avatar
winckel committed
307 308
    LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL);
    DevParam (N_RB_DL, 0, 0);
309 310 311 312 313 314 315
    break;
  }

}



316 317
uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL)
{
318 319 320 321 322

  uint32_t nprb=0,i;

  switch (N_RB_DL) {
  case 6:
323
    for (i=0; i<6; i++) {
324
      if ((rb_alloc&(1<<i)) != 0)
325
        nprb += 1;
326
    }
327

328
    break;
329

330 331
  case 25:
    if (ra_header == 0) {// Type 0 Allocation
332 333 334 335

      for (i=12; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          nprb += 2;
336
      }
337

338
      if ((rb_alloc&1) != 0)
339 340 341 342 343
        nprb += 1;
    } else {
      for (i=0; i<11; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
344 345
      }
    }
346

347
    break;
348

349 350
  case 50:
    if (ra_header == 0) {// Type 0 Allocation
351 352 353 354

      for (i=0; i<16; i++) {
        if ((rb_alloc&(1<<(16-i))) != 0)
          nprb += 3;
355
      }
356

357
      if ((rb_alloc&1) != 0)
358
        nprb += 2;
359

360 361 362 363
    } else {
      for (i=0; i<17; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
364 365
      }
    }
366

367
    break;
368

369 370
  case 100:
    if (ra_header == 0) {// Type 0 Allocation
371 372 373 374

      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(24-i))) != 0)
          nprb += 4;
375
      }
376 377 378 379
    } else {
      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
380 381
      }
    }
382

383
    break;
winckel's avatar
winckel committed
384 385 386 387 388

  default:
    LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL);
    DevParam (N_RB_DL, 0, 0);
    break;
389 390 391 392 393
  }

  return(nprb);
}

394 395
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs)
{
396

397
  uint16_t RIV;
398

399 400 401 402
  if (Lcrbs<=(1+(N_RB_DL>>1)))
    RIV = (N_RB_DL*(Lcrbs-1)) + RBstart;
  else
    RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart);
403

404
  return(RIV);
405 406
}

407
// Convert a DCI Format 1C RIV to a Format 1A RIV
408
// This extracts the start and length in PRBs from the 1C rballoc and
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
// recomputes the RIV as if it were the 1A rballoc

uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) {

  int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart;

  switch (N_RB_DL) {

  case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3
    NpDLVRB   = 3;
    N_RB_step = 2;
    break;
  case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12
    NpDLVRB   = 12;
    N_RB_step = 2;
    break;
  case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11
    NpDLVRB   = 11;
    N_RB_step = 4;
    break;
  case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24
    NpDLVRB   = 24;
    N_RB_step = 4;
    break;
  default:
    NpDLVRB   = 24;
    N_RB_step = 4;
    break;
  }

  // This is the 1C part from 7.1.6.3 in 36.213
  LpCRBsm1 = rballoc/NpDLVRB;
  //  printf("LpCRBs = %d\n",LpCRBsm1+1);

  if (LpCRBsm1 <= (NpDLVRB/2)) {
    RBpstart = rballoc % NpDLVRB;
  }
  else {
    LpCRBsm1 = NpDLVRB-LpCRBsm1;
    RBpstart = NpDLVRB-(rballoc%NpDLVRB);
  }
  //  printf("RBpstart %d\n",RBpstart);
  return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1)));
452

453 454
}

455
uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
456 457 458 459

  int offset;

  switch (N_RB_DL) {
460

461 462 463
  case 6:
  // N_RB_DL = tildeN_RB_DL = 6
  // Ngap = 4 , P=1, Nrow = 2, Nnull = 2
464

465 466 467 468 469 470 471 472 473 474
    switch (vrb) {
    case 0:  // even: 0->0, 1->2, odd: 0->3, 1->5
    case 1:
      return ((3*odd_slot) + 2*(vrb&3))%6;
      break;
    case 2:  // even: 2->3, 3->5, odd: 2->0, 3->2
    case 3:
      return ((3*odd_slot) + 2*(vrb&3) + 5)%6;
      break;
    case 4:  // even: 4->1, odd: 4->4
475
      return ((3*odd_slot) + 1)%6;
476 477 478 479 480
    case 5:  // even: 5->4, odd: 5->1
      return ((3*odd_slot) + 4)%6;
      break;
    }
    break;
481

482 483 484
  case 15:
    if (vrb<12) {
      if ((vrb&3) < 2)     // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11
485
  return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14);
486
      else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13
487
  return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
488 489 490 491 492 493 494
    }
    if (vrb==12)
      return (3+(7*odd_slot)) % 14;
    if (vrb==13)
      return (10+(7*odd_slot)) % 14;
    return 14;
    break;
495

496 497 498
  case 25:
    return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24);
    break;
499

500 501 502 503
  case 50: // P=3
    if (Ngap==0) {
      // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27
      if (vrb>=23)
504
  offset=4;
505
      else
506
  offset=0;
507
      if (vrb<44) {
508 509 510 511
  if ((vrb&3)>=2)
    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46;
  else
    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46;
512 513
      }
      if (vrb==44)  // even: 44->11, odd: 45->34
514
  return offset+((23*odd_slot) + 22-12+1);
515
      if (vrb==45)  // even: 45->10, odd: 45->33
516
  return offset+((23*odd_slot) + 22+12);
517
      if (vrb==46)
518
  return offset+46+((23*odd_slot) + 23-12+1) % 46;
519
      if (vrb==47)
520
  return offset+46+((23*odd_slot) + 23+12) % 46;
521
      if (vrb==48)
522
  return offset+46+((23*odd_slot) + 23-12+1) % 46;
523
      if (vrb==49)
524
  return offset+46+((23*odd_slot) + 23+12) % 46;
525 526 527 528
    }
    else {
      // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
      if (vrb>=9)
529
  offset=18;
530
      else
531
  offset=0;
532

533
      if (vrb<12) {
534 535 536 537
  if ((vrb&3)>=2)
    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18;
  else
    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18;
538 539
      }
      else {
540
  return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18);
541 542 543 544 545 546
      }
    }
    break;
  case 75:
    // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0
    if (Ngap ==0) {
547
      return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64);
548 549
    } else {
      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
550
      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
551 552 553 554 555
    }
    break;
  case 100:
    // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0
    if (Ngap ==0) {
556
      return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96);
557 558
    } else {
      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
559
      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
560 561 562 563 564 565 566
    }
    break;
  default:
    LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL);
    return 0;
  }
  return 0;
567

568 569
}

570

571 572
void generate_RIV_tables()
{
573 574 575 576

  // 6RBs localized RIV
  uint8_t Lcrbs,RBstart;
  uint16_t RIV;
577 578 579 580 581
  uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd;
  uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd;
  uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd;
  uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd;
  uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist;
582

583
  for (RBstart=0; RBstart<6; RBstart++) {
584
    alloc0 = 0;
585 586
    allocdist0_0_even = 0;
    allocdist0_0_odd  = 0;
587
    for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) {
588
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
589 590 591 592
      nVRB             = Lcrbs-1+RBstart;
      alloc0          |= (1<<nVRB);
      allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0));
      allocdist0_0_odd  |= (1<<get_prb(6,1,nVRB,0));
593
      RIV=computeRIV(6,RBstart,Lcrbs);
594

595
      if (RIV>RIV_max6)
596
        RIV_max6 = RIV;
597 598 599

      //      printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
      localRIV2alloc_LUT6[RIV] = alloc0;
600 601
      distRIV2alloc_even_LUT6[RIV]  = allocdist0_0_even;
      distRIV2alloc_odd_LUT6[RIV]  = allocdist0_0_odd;
602 603 604 605 606 607
      RIV2nb_rb_LUT6[RIV]      = Lcrbs;
      RIV2first_rb_LUT6[RIV]   = RBstart;
    }
  }


608
  for (RBstart=0; RBstart<25; RBstart++) {
609
    alloc0 = 0;
610 611
    allocdist0_0_even = 0;
    allocdist0_0_odd  = 0;
612
    for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) {
613
      nVRB = Lcrbs-1+RBstart;
614
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
615 616 617
      alloc0     |= (1<<nVRB);
      allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0));
      allocdist0_0_odd  |= (1<<get_prb(25,1,nVRB,0));
618

619
      //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd);
620
      RIV=computeRIV(25,RBstart,Lcrbs);
621

622
      if (RIV>RIV_max25)
623
        RIV_max25 = RIV;;
624

625 626 627 628 629 630

      localRIV2alloc_LUT25[RIV]      = alloc0;
      distRIV2alloc_even_LUT25[RIV]  = allocdist0_0_even;
      distRIV2alloc_odd_LUT25[RIV]   = allocdist0_0_odd;
      RIV2nb_rb_LUT25[RIV]           = Lcrbs;
      RIV2first_rb_LUT25[RIV]        = RBstart;
631
    }
632 633 634
  }


635
  for (RBstart=0; RBstart<50; RBstart++) {
636 637
    alloc0 = 0;
    alloc1 = 0;
638 639 640 641 642 643 644 645
    allocdist0_0_even=0;
    allocdist1_0_even=0;
    allocdist0_0_odd=0;
    allocdist1_0_odd=0;
    allocdist0_1_even=0;
    allocdist1_1_even=0;
    allocdist0_1_odd=0;
    allocdist1_1_odd=0;
646 647

    for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) {
648

649
      nVRB = Lcrbs-1+RBstart;
650

651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667

      if (nVRB<32)
        alloc0 |= (1<<nVRB);
      else
        alloc1 |= (1<<(nVRB-32));

      // Distributed Gap1, even slot
      nVRB_even_dist = get_prb(50,0,nVRB,0);
      if (nVRB_even_dist<32)
        allocdist0_0_even |= (1<<nVRB_even_dist);
      else
        allocdist1_0_even |= (1<<(nVRB_even_dist-32));

      // Distributed Gap1, odd slot
      nVRB_odd_dist = get_prb(50,1,nVRB,0);
      if (nVRB_odd_dist<32)
        allocdist0_0_odd |= (1<<nVRB_odd_dist);
668
      else
669
        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
670

671 672 673 674
      // Distributed Gap2, even slot
      nVRB_even_dist = get_prb(50,0,nVRB,1);
      if (nVRB_even_dist<32)
        allocdist0_1_even |= (1<<nVRB_even_dist);
675
      else
676
        allocdist1_1_even |= (1<<(nVRB_even_dist-32));
677

678 679 680 681
      // Distributed Gap2, odd slot
      nVRB_odd_dist = get_prb(50,1,nVRB,1);
      if (nVRB_odd_dist<32)
        allocdist0_1_odd |= (1<<nVRB_odd_dist);
682
      else
683
        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
684 685

      RIV=computeRIV(50,RBstart,Lcrbs);
686

687
      if (RIV>RIV_max50)
688
        RIV_max50 = RIV;
689 690

      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
691 692 693 694 695 696 697 698 699 700
      localRIV2alloc_LUT50_0[RIV]      = alloc0;
      localRIV2alloc_LUT50_1[RIV]      = alloc1;
      distRIV2alloc_gap0_even_LUT50_0[RIV]  = allocdist0_0_even;
      distRIV2alloc_gap0_even_LUT50_1[RIV]  = allocdist1_0_even;
      distRIV2alloc_gap0_odd_LUT50_0[RIV]   = allocdist0_0_odd;
      distRIV2alloc_gap0_odd_LUT50_1[RIV]   = allocdist1_0_odd;
      distRIV2alloc_gap1_even_LUT50_0[RIV]  = allocdist0_1_even;
      distRIV2alloc_gap1_even_LUT50_1[RIV]  = allocdist1_1_even;
      distRIV2alloc_gap1_odd_LUT50_0[RIV]   = allocdist0_1_odd;
      distRIV2alloc_gap1_odd_LUT50_1[RIV]   = allocdist1_1_odd;
701 702 703 704 705 706
      RIV2nb_rb_LUT50[RIV]        = Lcrbs;
      RIV2first_rb_LUT50[RIV]     = RBstart;
    }
  }


707
  for (RBstart=0; RBstart<100; RBstart++) {
708 709 710 711
    alloc0 = 0;
    alloc1 = 0;
    alloc2 = 0;
    alloc3 = 0;
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
    allocdist0_0_even=0;
    allocdist1_0_even=0;
    allocdist2_0_even=0;
    allocdist3_0_even=0;
    allocdist0_0_odd=0;
    allocdist1_0_odd=0;
    allocdist2_0_odd=0;
    allocdist3_0_odd=0;
    allocdist0_1_even=0;
    allocdist1_1_even=0;
    allocdist2_1_even=0;
    allocdist3_1_even=0;
    allocdist0_1_odd=0;
    allocdist1_1_odd=0;
    allocdist2_1_odd=0;
    allocdist3_1_odd=0;
728

729
    for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) {
730

731 732 733 734 735
      nVRB = Lcrbs-1+RBstart;

      if (nVRB<32)
        alloc0 |= (1<<nVRB);
      else if (nVRB<64)
736
        alloc1 |= (1<<(nVRB-32));
737
      else if (nVRB<96)
738
        alloc2 |= (1<<(nVRB-64));
739
      else
740
        alloc3 |= (1<<(nVRB-96));
741 742 743 744

      // Distributed Gap1, even slot
      nVRB_even_dist = get_prb(100,0,nVRB,0);

745
//      if ((RBstart==0) && (Lcrbs<=8))
746
//  printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);
747 748 749 750 751 752 753


      if (nVRB_even_dist<32)
        allocdist0_0_even |= (1<<nVRB_even_dist);
      else if (nVRB_even_dist<64)
        allocdist1_0_even |= (1<<(nVRB_even_dist-32));
      else if (nVRB_even_dist<96)
754
  allocdist2_0_even |= (1<<(nVRB_even_dist-64));
755
      else
756
  allocdist3_0_even |= (1<<(nVRB_even_dist-96));
757
/*      if ((RBstart==0) && (Lcrbs<=8))
758 759 760 761 762 763
  printf("rballoc =>(%08x.%08x.%08x.%08x)\n",
         allocdist0_0_even,
         allocdist1_0_even,
         allocdist2_0_even,
         allocdist3_0_even
         );
764
*/
765 766 767 768 769 770 771
      // Distributed Gap1, odd slot
      nVRB_odd_dist = get_prb(100,1,nVRB,0);
      if (nVRB_odd_dist<32)
        allocdist0_0_odd |= (1<<nVRB_odd_dist);
      else if (nVRB_odd_dist<64)
        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
      else if (nVRB_odd_dist<96)
772
  allocdist2_0_odd |= (1<<(nVRB_odd_dist-64));
773
      else
774
  allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));
775 776


777 778 779 780 781 782 783
      // Distributed Gap2, even slot
      nVRB_even_dist = get_prb(100,0,nVRB,1);
      if (nVRB_even_dist<32)
        allocdist0_1_even |= (1<<nVRB_even_dist);
      else if (nVRB_even_dist<64)
        allocdist1_1_even |= (1<<(nVRB_even_dist-32));
      else if (nVRB_even_dist<96)
784
  allocdist2_1_even |= (1<<(nVRB_even_dist-64));
785
      else
786
  allocdist3_1_even |= (1<<(nVRB_even_dist-96));
787 788 789 790 791 792 793 794 795


      // Distributed Gap2, odd slot
      nVRB_odd_dist = get_prb(100,1,nVRB,1);
      if (nVRB_odd_dist<32)
        allocdist0_1_odd |= (1<<nVRB_odd_dist);
      else if (nVRB_odd_dist<64)
        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
      else if (nVRB_odd_dist<96)
796
  allocdist2_1_odd |= (1<<(nVRB_odd_dist-64));
797
      else
798
  allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));
799

800 801

      RIV=computeRIV(100,RBstart,Lcrbs);
802

803
      if (RIV>RIV_max100)
804
        RIV_max100 = RIV;
805 806 807 808 809 810

      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
      localRIV2alloc_LUT100_0[RIV] = alloc0;
      localRIV2alloc_LUT100_1[RIV] = alloc1;
      localRIV2alloc_LUT100_2[RIV] = alloc2;
      localRIV2alloc_LUT100_3[RIV] = alloc3;
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
      distRIV2alloc_gap0_even_LUT100_0[RIV]  = allocdist0_0_even;
      distRIV2alloc_gap0_even_LUT100_1[RIV]  = allocdist1_0_even;
      distRIV2alloc_gap0_even_LUT100_2[RIV]  = allocdist2_0_even;
      distRIV2alloc_gap0_even_LUT100_3[RIV]  = allocdist3_0_even;
      distRIV2alloc_gap0_odd_LUT100_0[RIV]   = allocdist0_0_odd;
      distRIV2alloc_gap0_odd_LUT100_1[RIV]   = allocdist1_0_odd;
      distRIV2alloc_gap0_odd_LUT100_2[RIV]   = allocdist2_0_odd;
      distRIV2alloc_gap0_odd_LUT100_3[RIV]   = allocdist3_0_odd;
      distRIV2alloc_gap1_even_LUT100_0[RIV]  = allocdist0_1_even;
      distRIV2alloc_gap1_even_LUT100_1[RIV]  = allocdist1_1_even;
      distRIV2alloc_gap1_even_LUT100_2[RIV]  = allocdist2_1_even;
      distRIV2alloc_gap1_even_LUT100_3[RIV]  = allocdist3_1_even;
      distRIV2alloc_gap1_odd_LUT100_0[RIV]   = allocdist0_1_odd;
      distRIV2alloc_gap1_odd_LUT100_1[RIV]   = allocdist1_1_odd;
      distRIV2alloc_gap1_odd_LUT100_2[RIV]   = allocdist2_1_odd;
      distRIV2alloc_gap1_odd_LUT100_3[RIV]   = allocdist3_1_odd;

828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
      RIV2nb_rb_LUT100[RIV]      = Lcrbs;
      RIV2first_rb_LUT100[RIV]   = RBstart;
    }
  }
}

// Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2
// permutation for even slots :
//    n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6)
//    n_PRB''(0,1,2,3) = (0,2,4,6)
//    => n_tilde_PRB(5) = (4)
//       n_tilde_PRB(4) = (1)
//       n_tilde_PRB(2,3) = (3,5)
//       n_tilde_PRB(0,1) = (0,2)



845
uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci)
846
{
847

848
  return(localRIV2alloc_LUT25[rb_alloc_dci]);
849 850 851

}

852 853
uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti)
{
854 855 856
  unsigned char UE_id;

  // find the UE_index corresponding to rnti
857
  UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
858
  DevAssert( UE_id != (unsigned char)-1 );
859

860
  return(PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]);
861 862
}

863
int generate_eNB_dlsch_params_from_dci(int frame,
864
                                       uint8_t subframe,
865 866 867 868 869 870 871 872 873
                                       void *dci_pdu,
                                       uint16_t rnti,
                                       DCI_format_t dci_format,
                                       LTE_eNB_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
                                       uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
Elena Lukashova's avatar
Elena Lukashova committed
874
                                       uint16_t DL_pmi_single
875
                                      )
876
{
877

winckel's avatar
winckel committed
878 879 880
  uint8_t harq_pid = UINT8_MAX;
  uint32_t rballoc = UINT32_MAX;
  uint32_t RIV_max = 0;
881
  uint8_t NPRB,tbswap,tpmi=0;
882
  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
883 884
  uint8_t frame_type=frame_parms->frame_type;
  uint8_t vrb_type=0;
knopp's avatar
 
knopp committed
885
  uint8_t mcs=0,mcs1=0,mcs2=0;
886
  uint8_t I_mcs = 0;
knopp's avatar
 
knopp committed
887
  uint8_t rv=0,rv1=0,rv2=0;
888 889
  uint8_t rah=0;
  uint8_t TPC=0;
890
  uint8_t TB0_active=0,TB1_active=0;
891
  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
knopp's avatar
 
knopp committed
892

893 894 895 896 897 898 899
  //   printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);

  switch (dci_format) {

  case format0:
    return(-1);
    break;
900

901 902
  case format1A:  // This is DLSCH allocation for control traffic

903

904 905 906

    dlsch[0]->subframe_tx[subframe] = 1;

907

908 909 910
    switch (frame_parms->N_RB_DL) {
    case 6:
      if (frame_type == TDD) {
911 912 913 914 915 916
        vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
917

918 919 920 921 922 923 924 925
        //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
        vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
926

927
        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
928
      }
929 930

      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
931
      dlsch0_harq->codeword=0;
932

933
      if (vrb_type==LOCALIZED) {
934
  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rballoc];
935 936
      }
      else {
937 938
  LOG_E(PHY,"Distributed RB allocation not done yet\n");
  mac_xface->macphy_exit("exiting");
939
      }
940 941
      dlsch0_harq->vrb_type       = vrb_type;
      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT6[rballoc];//NPRB;
942 943
      RIV_max = RIV_max6;

944

945
      break;
946

947 948
    case 25:
      if (frame_type == TDD) {
949 950 951 952 953 954
        vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
955

956 957 958 959 960 961 962 963
        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
        vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid;
964

965
        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
966 967
      }

968
      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
969

970

971
      if (vrb_type==LOCALIZED) {
972
  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rballoc];
973 974
      }
      else {
975 976
  LOG_E(PHY,"Distributed RB allocation not done yet\n");
  mac_xface->macphy_exit("exiting");
977
      }
978 979 980
      dlsch0_harq->vrb_type       = vrb_type;
      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT25[rballoc];//NPRB;
      RIV_max                     = RIV_max25;
981
      break;