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

22 23 24
/* file: lte_rate_matching.c
   purpose: Procedures for rate matching/interleaving for LTE (turbo-coded transport channels) (TX/RX)
   author: raymond.knopp@eurecom.fr
25
   date: 21.10.2009
26 27 28 29 30
*/
#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#endif
31
#include "PHY/defs.h"
32
#include "assertions.h"
33 34 35

//#define cmin(a,b) ((a)<(b) ? (a) : (b))

36 37
static uint32_t bitrev[32]    = {0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31};
static uint32_t bitrev_x3[32] = {0,48,24,72,12,60,36,84,6,54,30,78,18,66,42,90,3,51,27,75,15,63,39,87,9,57,33,81,21,69,45,93};
38 39 40 41 42 43
static uint32_t bitrev_cc[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};

//#define RM_DEBUG_TX 1
//#define RM_DEBUG 1
//#define RM_DEBUG2 1
//#define RM_DEBUG_CC 1
44 45 46

uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
{
47 48

  uint32_t RTC = (D>>5), ND, ND3;
knopp's avatar
knopp committed
49
  uint32_t row,col,Kpi;
50
  uint32_t index3,k,k2;
51
#ifdef RM_DEBUG
52
  uint32_t nulled=0;
53
#endif
54 55 56 57
  uint8_t *d1,*d2,*d3;

  if ((D&0x1f) > 0)
    RTC++;
58

59 60 61
  Kpi = (RTC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
62
#ifdef RM_DEBUG
63 64
  printf("sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3);
  printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND);
65
#endif
66 67 68 69
  ND3 = ND*3;

  // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
  d[(3*D)+2] = d[2];
70 71
  k=0;
  k2=0;
72 73 74 75
  d1 = d-ND3;
  d2 = d1+1;
  d3 = d1+5;

76
  for (col=0; col<32; col++) {
77 78 79 80
#ifdef RM_DEBUG
    printf("Col %d\n",col);
#endif
    index3 = bitrev_x3[col];//3*index;
81 82

    for (row=0; row<RTC; row++) {
83 84 85

      w[k]            =  d1[index3];//d[index3-ND3];
      w[Kpi+k2]       =  d2[index3];//d[index3-ND3+1];
86
      w[Kpi+1+k2]     =  d3[index3];//d[index3-ND3+5];
87 88 89 90


#ifdef RM_DEBUG
      printf("row %d, index %d, index-Nd %d index-Nd+1 %d (k,Kpi+2k,Kpi+2k+1) (%d,%d,%d) w(%d,%d,%d)\n",row,index,index-ND,((index+1)%Kpi)-ND,k,Kpi+(k<<1),Kpi+(k<<1)+1,w[k],w[Kpi+(k<<1)],w[Kpi+1+(k<<1)]);
91

92
      if (w[k]== LTE_NULL)
93 94
        nulled++;

95
      if (w[Kpi+(k<<1)] ==LTE_NULL)
96 97
        nulled++;

98
      if (w[Kpi+1+(k<<1)] ==LTE_NULL)
99 100
        nulled++;

101 102
#endif
      index3+=96;
knopp's avatar
knopp committed
103
      k++;k2+=2;
104
    }
105 106 107 108
  }

  if (ND>0)
    w[(3*Kpi) - 1] = LTE_NULL;
109

110
#ifdef RM_DEBUG
111

112 113 114 115
  if (ND>0) {
    printf("RM_TX: Nulled last component in pos %d\n",Kpi-1+k2);
    nulled++;
  }
116

117 118 119 120 121 122
  printf("RM_TX: Nulled %d\n",nulled);
#endif
  return(RTC);
}


123 124
uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
{
125 126 127 128 129 130 131 132 133 134

  uint32_t RCC = (D>>5), ND, ND3;
  uint32_t row,col,Kpi,index;
  uint32_t index3,k;
#ifdef RM_DEBUG_CC
  uint32_t nulled=0;
#endif

  if ((D&0x1f) > 0)
    RCC++;
135

136 137 138 139 140 141 142 143 144 145
  Kpi = (RCC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
#ifdef RM_DEBUG_CC
  printf("sub_block_interleaving_cc : D = %d (%d), d %p, w %p\n",D,D*3,d,w);
  printf("RCC = %d, Kpi=%d, ND=%d\n",RCC,Kpi,ND);
#endif
  ND3 = ND*3;

  k=0;
146 147

  for (col=0; col<32; col++) {
148 149 150 151 152
#ifdef RM_DEBUG_CC
    printf("Col %d\n",col);
#endif
    index = bitrev_cc[col];
    index3 = 3*index;
153 154

    for (row=0; row<RCC; row++) {
155 156
      w[k]          =  d[(int32_t)index3-(int32_t)ND3];
      w[Kpi+k]     =   d[(int32_t)index3-(int32_t)ND3+1];
157
      w[(Kpi<<1)+k] =  d[(int32_t)index3-(int32_t)ND3+2];
158 159
#ifdef RM_DEBUG_CC
      printf("row %d, index %d k %d w(%d,%d,%d)\n",row,index,k,w[k],w[Kpi+k],w[(Kpi<<1)+k]);
160

161
      if (w[k]== LTE_NULL)
162 163
        nulled++;

164
      if (w[Kpi+k] ==LTE_NULL)
165 166
        nulled++;

167
      if (w[(Kpi<<1)+k] ==LTE_NULL)
168 169
        nulled++;

170 171 172 173
#endif
      index3+=96;
      index+=32;
      k++;
174
    }
175
  }
176

177 178 179 180 181 182
#ifdef RM_DEBUG_CC
  printf("RM_TX: Nulled %d\n",nulled);
#endif
  return(RCC);
}

183 184
void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w)
{
185 186 187 188 189 190 191 192

  uint32_t RTC = (D>>5), ND, ND3;
  uint32_t row,col,Kpi,index;
  uint32_t index3,k,k2;
  int16_t *d1,*d2,*d3;

  if ((D&0x1f) > 0)
    RTC++;
193

194 195 196 197 198 199 200 201 202 203
  Kpi = (RTC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
#ifdef RM_DEBUG2
  printf("sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3);
  printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND);
#endif
  ND3 = ND*3;

  // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
204 205
  k=0;
  k2=0;
206 207 208 209
  d1 = d-ND3;
  d2 = d1+1;
  d3 = d1+5;

210
  for (col=0; col<32; col++) {
211 212 213 214 215
#ifdef RM_DEBUG2
    printf("Col %d\n",col);
#endif
    index = bitrev[col];
    index3 = bitrev_x3[col];//3*index;
216 217

    for (row=0; row<RTC; row++) {
218 219

      d1[index3]   = w[k];
220 221
      d2[index3]   = w[Kpi+k2];
      d3[index3]   = w[Kpi+1+k2];
222 223
      index3+=96;
      index+=32;
224 225 226 227
      k++;
      k2++;
      k2++;
    }
228
  }
229 230 231

  //  if (ND>0)
  //    d[2] = LTE_NULL;//d[(3*D)+2];
232 233 234

}

235 236
void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w)
{
237 238 239 240 241 242 243 244 245 246 247

  //WANG_Hao uint32_t RCC = (D>>5), ND, ND3;
  uint32_t RCC = (D>>5);
  ptrdiff_t   ND, ND3;
  uint32_t row,col,Kpi,index;
  //WANG_Hao uint32_t index3,k;
  ptrdiff_t index3;
  uint32_t k;

  if ((D&0x1f) > 0)
    RCC++;
248

249 250 251 252 253 254 255 256 257 258
  Kpi = (RCC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
#ifdef RM_DEBUG2
  printf("sub_block_interleaving_cc : D = %d (%d), d %p, w %p\n",D,D*3,d,w);
  printf("RCC = %d, Kpi=%d, ND=%d\n",RCC,Kpi,ND);
#endif
  ND3 = ND*3;

  k=0;
259 260

  for (col=0; col<32; col++) {
261 262 263 264 265
#ifdef RM_DEBUG2
    printf("Col %d\n",col);
#endif
    index = bitrev_cc[col];
    index3 = 3*index;
266 267

    for (row=0; row<RCC; row++) {
268 269

      d[index3-ND3]   = w[k];
270 271
      d[index3-ND3+1] = w[Kpi+k];
      d[index3-ND3+2] = w[(Kpi<<1)+k];
272 273 274 275 276 277
#ifdef RM_DEBUG2
      printf("row %d, index %d k %d index3-ND3 %d w(%d,%d,%d)\n",row,index,k,index3-ND3,w[k],w[Kpi+k],w[(Kpi<<1)+k]);
#endif
      index3+=96;
      index+=32;
      k++;
278
    }
279 280 281 282
  }

}

283 284
uint32_t generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F)
{
285 286 287 288 289 290 291 292 293 294 295

  uint32_t RTC = (D>>5), ND;
  uint32_t col,Kpi,index;
  int32_t k,k2;
#ifdef RM_DEBUG
  uint32_t nulled=0;
#endif
  uint8_t *wKpi,*wKpi1,*wKpi2,*wKpi4;

  if ((D&0x1f) > 0)
    RTC++;
296

297 298 299 300 301 302 303
  Kpi = (RTC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
#ifdef RM_DEBUG
  printf("dummy sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3);
  printf("RTC = %d, Kpi=%d, ND=%d, F=%d (Nulled %d)\n",RTC,Kpi,ND,F,(2*F + 3*ND));
#endif
304 305


306 307 308 309 310 311
  k=0;
  k2=0;
  wKpi = &w[Kpi];
  wKpi1 = &w[Kpi+1];
  wKpi2 = &w[Kpi+2];
  wKpi4 = &w[Kpi+4];
312 313

  for (col=0; col<32; col++) {
314 315 316 317
#ifdef RM_DEBUG
    printf("Col %d\n",col);
#endif
    index = bitrev[col];
318

319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
    if (index<(ND+F)) {
      w[k]   =  LTE_NULL;
      wKpi[k2] = LTE_NULL;
#ifdef RM_DEBUG
      nulled+=2;
#endif
    }

    //bits beyond 32 due to "filler" bits
    if ((index+32)<(ND+F)) {
      w[k+1]   =  LTE_NULL;
      wKpi2[k2] = LTE_NULL;
#ifdef RM_DEBUG
      nulled+=2;
#endif
    }
335

336 337 338 339 340 341 342 343 344 345 346 347 348 349
    if ((index+64)<(ND+F)) {
      w[k+2]   =  LTE_NULL;
      wKpi4[k2] = LTE_NULL;
#ifdef RM_DEBUG
      nulled+=2;
#endif
    }

    if ((index+1)<ND) {
      wKpi1[k2] =  LTE_NULL;
#ifdef RM_DEBUG
      nulled+=1;
#endif
    }
350

351 352 353 354 355 356 357
#ifdef RM_DEBUG
    printf("k %d w (%d,%d,%d) w+1 (%d,%d,%d), index %d index-ND-F %d index+32-ND-F %d\n",k,w[k],w[Kpi+(k<<1)],w[Kpi+1+(k<<1)],w[k+1],w[2+Kpi+(k<<1)],w[2+Kpi+1+(k<<1)],index,index-ND-F,index+32-ND-F);
#endif
    k+=RTC;
    k2=k<<1;
  }

358
  // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
359 360
  if (ND>0)
    w[(3*Kpi)-1] = LTE_NULL;
361

362
#ifdef RM_DEBUG
363

364 365 366 367
  if (ND>0) {
    nulled++;
    printf("dummy_w: Nulled final position %d\n",(3*Kpi)-1);
  }
368

369 370 371 372 373
  printf("Nulled = %d\n",nulled);
#endif
  return(RTC);
}

374 375
uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
{
376 377 378

  uint32_t RCC = (D>>5), ND;
  uint32_t col,Kpi,index;
379
  int32_t k;
380 381 382 383 384 385
#ifdef RM_DEBUG_CC
  uint32_t nulled=0;
#endif

  if ((D&0x1f) > 0)
    RCC++;
386

387 388 389 390 391 392 393 394 395 396 397 398
  Kpi = (RCC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
#ifdef RM_DEBUG_CC
  printf("dummy sub_block_interleaving_cc : D = %d (%d)\n",D,D*3);
  printf("RCC = %d, Kpi=%d, ND=%d, (Nulled %d)\n",RCC,Kpi,ND,3*ND);
#endif
  //  ND3 = ND*3;

  // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
  k=0;

399
  for (col=0; col<32; col++) {
400 401 402 403
#ifdef RM_DEBUG_CC
    printf("Col %d\n",col);
#endif
    index = bitrev_cc[col];
404

405 406 407 408 409 410 411 412
    if (index<ND) {
      w[k]          = LTE_NULL;
      w[Kpi+k]      = LTE_NULL;
      w[(Kpi<<1)+k] = LTE_NULL;
#ifdef RM_DEBUG_CC
      nulled+=3;
#endif
    }
413

414 415 416 417 418 419
    /*
    //bits beyond 32 due to "filler" bits
    if (index+32<ND) {
      w[k+1]          = LTE_NULL;
      w[Kpi+1+k]      = LTE_NULL;
      w[(Kpi<<1)+1+k] = LTE_NULL;
420
    #ifdef RM_DEBUG
421
      nulled+=3;
422
    #endif
423 424 425 426 427
    }
    if (index+64<ND) {
      w[k+2]          = LTE_NULL;
      w[Kpi+2+k]      = LTE_NULL;
      w[(Kpi<<1)+2+k] = LTE_NULL;
428
    #ifdef RM_DEBUG
429
      nulled+=3;
430
    #endif
431 432 433 434 435
    }


    if ((index+1)<ND) {
      w[Kpi+1+(k<<1)] =  LTE_NULL;
436
    #ifdef RM_DEBUG
437
      nulled+=1;
438
    #endif
439
    }
440
    */
441 442 443 444 445 446 447 448 449 450 451 452 453 454
#ifdef RM_DEBUG_CC
    printf("k %d w (%d,%d,%d), index-ND %d index+32-ND %d\n",k,w[k],w[Kpi+k],w[(Kpi<<1)+k],index-ND,index+32-ND);
#endif
    k+=RCC;
  }

#ifdef RM_DEBUG_CC
  printf("Nulled = %d\n",nulled);
#endif
  return(RCC);
}


uint32_t lte_rate_matching_turbo(uint32_t RTC,
455 456 457 458 459 460 461 462 463 464 465
                                 uint32_t G,
                                 uint8_t *w,
                                 uint8_t *e,
                                 uint8_t C,
                                 uint32_t Nsoft,
                                 uint8_t Mdlharq,
                                 uint8_t Kmimo,
                                 uint8_t rvidx,
                                 uint8_t Qm,
                                 uint8_t Nl,
                                 uint8_t r,
466 467
                                 uint8_t nb_rb) 
//                                 uint8_t m)
468 469 470
{


471 472 473 474
  uint32_t Nir,Ncb,Gp,GpmodC,E,Ncbmod,ind,k;
  //  int cnt=0;
  uint8_t *e2;
#ifdef RM_DEBUG_TX
475
  int code_block,round;
476 477 478 479 480 481 482 483 484 485
  int cnt;
  int zeroed=0;
  int oned=0;
  int twoed=0;
  int threed =0;
  uint32_t nulled=0;
  static unsigned char *counter_buffer[MAX_NUM_DLSCH_SEGMENTS][4];
  FILE *counter_fd;
  char fname[512];
#endif
486

487 488 489 490 491 492 493 494
  if (Mdlharq>0) {  // Downlink
    Nir = Nsoft/Kmimo/cmin(8,Mdlharq);
    Ncb = cmin(Nir/C,3*(RTC<<5));
  }
  else {  // Uplink
    Nir=0;
    Ncb = 3*(RTC<<5); // Kw
  }
495
#ifdef RM_DEBUG_TX
496 497 498 499 500 501

  if (rvidx==0 && r==0) {
    for(round=0; round<4; round++)
      for (code_block=0; code_block<MAX_NUM_DLSCH_SEGMENTS; code_block++) {
        counter_buffer[code_block][round] = (unsigned char *)malloc(Ncb*sizeof(char));
        memset(counter_buffer[code_block][round],0,Ncb*sizeof(char));
502
      }
503 504 505 506
  } else if(rvidx==3) {
    sprintf(fname, "mcs%d_rate_matching_RB_%d.txt", m, nb_rb);
    // sprintf(fname,"mcs0_rate_matching_RB_6.txt");
    counter_fd = fopen(fname,"w");
507
  }
508

509
#endif
510

511 512 513
  // if (rvidx==3)
  //  for (cnt=0;cnt<Ncb;cnt++)
  //    counter_buffer[rvidx][cnt]=0;
knopp's avatar
knopp committed
514 515
  if (Ncb>(3*(RTC<<5)))
    AssertFatal(1==0,"Exiting, RM condition (Ncb %d, RTC %d, Nir/C %d, Nsoft %d, Kw %d)\n",Ncb,RTC,Nir/C,Nsoft,3*(RTC<<5));
516
  
517 518
  AssertFatal(Nl>0,"Nl is 0\n");
  AssertFatal(Qm>0,"Qm is 0\n");
519 520 521 522
  Gp = G/Nl/Qm;
  GpmodC = Gp%C;

#ifdef RM_DEBUG
523
  printf("lte_rate_matching_turbo: Ncb %d, Kw %d, Nir/C %d, rvidx %d, G %d, Qm %d, Nl%d, r %d\n",Ncb,3*(RTC<<5),Nir/C,rvidx, G, Qm,Nl,r);
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
#endif

  if (r < (C-(GpmodC)))
    E = Nl*Qm * (Gp/C);
  else
    E = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));

  Ncbmod = Ncb%(RTC<<3);

  ind = RTC * (2+(rvidx*(((Ncbmod==0)?0:1) + (Ncb/(RTC<<3)))*2));

#ifdef RM_DEBUG_TX
  printf("lte_rate_matching_turbo: E %d, k0 %d, Ncbmod %d, Ncb/(RTC<<3) %d\n",E,ind,Ncbmod,Ncb/(RTC<<3));
#endif

539 540
  //e2=e+(r*E);
  e2 = e;
541

542 543
  k=0;

544
  for (; (ind<Ncb)&&(k<E); ind++) {
545
    //    e2[k]=w[ind];
546 547 548
#ifdef RM_DEBUG_TX
    printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
#endif
549

550
    if (w[ind] != LTE_NULL) e2[k++]=w[ind];
551
  }
552

553
  while(k<E) {
554
    for (ind=0; (ind<Ncb)&&(k<E); ind++) {
555
      //      e2[k] = w[ind];
556
#ifdef RM_DEBUG_TX
557
      printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
558
#endif
559

560
      if (w[ind] != LTE_NULL) e2[k++]=w[ind];
561 562
    }
  }
563 564

  /*
565
  for (k=0;k<E;k++) {
566

567 568

    while(w[ind] == LTE_NULL) {
569
  #ifdef RM_DEBUG_TX
570 571
      printf("RM_tx : ind %d, NULL\n",ind);
      nulled++;
572
  #endif
573 574
      ind++;
      if (ind==Ncb)
575
  ind=0;
576 577 578 579 580
    }

    e2[k] = w[ind];
    //    printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
    //    cnt = cnt+1;
581
  #ifdef RM_DEBUG_TX
582 583 584 585
    counter_buffer[r][rvidx][ind]++;
    // printf("Bit_Counter[%d][%d][%d]=%d\n",r,rvidx,ind,counter_buffer[r][rvidx][ind]);
    //    printf("k %d ind %d, w %c(%d)\n",k,ind,w[ind],w[ind]);
    // printf("RM_TX %d (%d) Ind: %d (%d)\n",k,k+r*E,ind,e2[k]);
586
  #endif
587 588 589 590
    ind++;
    if (ind==Ncb)
      ind=0;
  }
591 592

  #ifdef RM_DEBUG_TX
593 594 595
  if (rvidx==3){
    for(cnt=0;cnt<Ncb;cnt++)
      {
596 597 598 599 600 601
  fprintf(counter_fd,"%d %x %x %x %x %x %x %x %x %x %x %x %x\n",cnt,
    counter_buffer[0][0][cnt],counter_buffer[1][0][cnt],counter_buffer[2][0][cnt],
    counter_buffer[0][1][cnt],counter_buffer[1][1][cnt],counter_buffer[2][1][cnt],
    counter_buffer[0][2][cnt],counter_buffer[1][2][cnt],counter_buffer[2][2][cnt],
    counter_buffer[0][3][cnt],counter_buffer[1][3][cnt],counter_buffer[2][3][cnt]
    );
602 603
    }
    fclose(counter_fd);
604

605
  }
606 607


608 609 610 611 612 613 614 615 616 617 618 619
   for(cnt=0;cnt<Ncb;cnt++){
    printf("Bit_Counter[%d][%d]=%d\n",rvidx,cnt,counter_buffer[r][rvidx][cnt]);
    if(counter_buffer[r][rvidx][cnt]==0)
      zeroed++;
    else if(counter_buffer[r][rvidx][cnt]==1)
      oned++;
    else if(counter_buffer[r][rvidx][cnt]==2)
      twoed++;
    else if(counter_buffer[r][rvidx][cnt]==3)
      threed++;
   }

620 621 622 623 624
  printf("zeroed %d\n",zeroed);
  printf("oned %d\n",oned);
  printf("twoed %d\n",twoed);
  printf("threed %d\n",threed);

625
  printf("nulled %d\n",nulled);
626 627 628

  #endif
  */
629 630
  return(E);
}
631

632 633

uint32_t lte_rate_matching_cc(uint32_t RCC,
634 635 636 637 638
                              uint16_t E,
                              uint8_t *w,
                              uint8_t *e)
{

639 640 641

  uint32_t ind=0,k;

642
  uint16_t Kw = 3*(RCC<<5);
643 644 645 646 647 648 649

#ifdef RM_DEBUG_CC
  uint32_t nulled=0;

  printf("lte_rate_matching_cc: Kw %d, E %d\n",Kw, E);
#endif

650
  for (k=0; k<E; k++) {
651 652 653 654 655 656 657 658 659


    while(w[ind] == LTE_NULL) {

#ifdef RM_DEBUG_CC
      nulled++;
      printf("RM_TX_CC : ind %d, NULL\n",ind);
#endif
      ind++;
660

661
      if (ind==Kw)
662
        ind=0;
663 664 665 666 667
    }


    e[k] = w[ind];
#ifdef RM_DEBUG_CC
668
    //    printf("k %d ind %d, w %c(%d)\n",k,ind,w[ind],w[ind]);
669 670 671
    printf("RM_TX_CC %d Ind: %d (%d)\n",k,ind,e[k]);
#endif
    ind++;
672

673 674 675
    if (ind==Kw)
      ind=0;
  }
676

677 678 679 680 681 682 683 684
#ifdef RM_DEBUG_CC
  printf("nulled %d\n",nulled);
#endif
  return(E);
}


int lte_rate_matching_turbo_rx(uint32_t RTC,
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
                               uint32_t G,
                               int16_t *w,
                               uint8_t *dummy_w,
                               int16_t *soft_input,
                               uint8_t C,
                               uint32_t Nsoft,
                               uint8_t Mdlharq,
                               uint8_t Kmimo,
                               uint8_t rvidx,
                               uint8_t clear,
                               uint8_t Qm,
                               uint8_t Nl,
                               uint8_t r,
                               uint32_t *E_out)
{


702 703
  uint32_t Nir,Ncb,Gp,GpmodC,E,Ncbmod,ind,k;
  int16_t *soft_input2;
704
  //   int32_t w_tmp;
705 706 707
#ifdef RM_DEBUG
  int nulled=0;
#endif
708

709
  if (Kmimo==0 || C==0 || Qm==0 || Nl==0) {
710
    printf("lte_rate_matching.c: invalid parameters (Kmimo %d, Mdlharq %d, C %d, Qm %d, Nl %d\n",
711
        Kmimo,Mdlharq,C,Qm,Nl);
712 713 714
    return(-1);
  }

715 716 717 718 719 720 721 722
  if (Mdlharq>0) { // Downlink
    Nir = Nsoft/Kmimo/cmin(8,Mdlharq);
    Ncb = cmin(Nir/C,3*(RTC<<5));
  }
  else {  // Uplink
    Nir=0;
    Ncb = 3*(RTC<<5);
  }
723

724 725
  AssertFatal(Nl>0,"Nl is 0\n");
  AssertFatal(Qm>0,"Qm is 0\n");
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
  Gp = G/Nl/Qm;
  GpmodC = Gp%C;



  if (r < (C-(GpmodC)))
    E = Nl*Qm * (Gp/C);
  else
    E = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));

  Ncbmod = Ncb%(RTC<<3);

  ind = RTC * (2+(rvidx*(((Ncbmod==0)?0:1) + (Ncb/(RTC<<3)))*2));

#ifdef RM_DEBUG
  printf("lte_rate_matching_turbo_rx: Clear %d, E %d, Ncb %d, Kw %d, rvidx %d, G %d, Qm %d, Nl%d, r %d\n",clear,E,Ncb,3*(RTC<<5),rvidx, G, Qm,Nl,r);
#endif

  if (clear==1)
    memset(w,0,Ncb*sizeof(int16_t));
746

747
  soft_input2 = soft_input;// + (r*E);
748 749
  k=0;

750 751
  for (; (ind<Ncb)&&(k<E); ind++) {
    if (dummy_w[ind] != LTE_NULL) {
752 753 754 755
      /*
      if ((w[ind]>0 && soft_input2[k]<0) || 
	  (w[ind]<0 && soft_input2[k]>0))  
	  printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/
756
      w[ind] += soft_input2[k++];
757 758 759 760
#ifdef RM_DEBUG
      printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]);
#endif
    }
761

762 763 764 765 766
#ifdef RM_DEBUG
    else {
      printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
      nulled++;
    }
767

768 769
#endif
  }
770

771
  while(k<E) {
772 773 774
    for (ind=0; (ind<Ncb)&&(k<E); ind++) {
      if (dummy_w[ind] != LTE_NULL) {
        w[ind] += soft_input2[k++];
775
#ifdef RM_DEBUG
776
        printf("RM_RX k%d Ind: %d (%d)(soft in %d)\n",k-1,ind,w[ind],soft_input2[k-1]);
777 778
#endif
      }
779

780 781
#ifdef RM_DEBUG
      else {
782 783 784 785
        printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
        nulled++;
      }

786 787 788 789 790 791 792 793 794
#endif
    }
  }

  /*
  for (k=0;k<E;k++) {


    while(dummy_w[ind] == LTE_NULL) {
795
  #ifdef RM_DEBUG
796
      printf("RM_rx : ind %d, NULL\n",ind);
797
  #endif
798 799
      ind++;
      if (ind==Ncb)
800
  ind=0;
801 802
    }
  */
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
  /*
  if (w[ind] != 0)
    printf("repetition %d (%d,%d,%d)\n",ind,rvidx,E,Ncb);
  */
  // Maximum-ratio combining of repeated bits and retransmissions
  /*
  w_tmp = (int) w[ind] + (int) soft_input2[k];
  if (w_tmp > 32767) {
    //#ifdef DEBUG_RM
    printf("OVERFLOW!!!!!, w_tmp = %d\n",w_tmp);
    //#endif
    w[ind] = 32767;
  }
  else if (w_tmp < -32768) {
    //#ifdef DEBUG_RM
    printf("UNDERFLOW!!!!!, w_tmp = %d\n",w_tmp);
    //#endif
    w[ind] = -32768;
  }
  else
  */
824 825
  /*
    w[ind] += soft_input2[k];
826
  #ifdef RM_DEBUG
827
      printf("RM_RX k%d Ind: %d (%d)\n",k,ind,w[ind]);
828
  #endif
829 830 831 832 833 834 835 836 837 838 839 840 841
    ind++;
    if (ind==Ncb)
      ind=0;
  }
  */

  *E_out = E;
  return(0);

}


void lte_rate_matching_cc_rx(uint32_t RCC,
842 843 844 845 846 847 848
                             uint16_t E,
                             int8_t *w,
                             uint8_t *dummy_w,
                             int8_t *soft_input)
{


849 850

  uint32_t ind=0,k;
851
  uint16_t Kw = 3*(RCC<<5);
852 853 854 855 856 857 858 859 860 861 862 863
  uint32_t acc=1;
  int16_t w16[Kw];
#ifdef RM_DEBUG_CC
  uint32_t nulled=0;

  printf("lte_rate_matching_cc_rx: Kw %d, E %d, w %p, soft_input %p\n",3*(RCC<<5),E,w,soft_input);
#endif


  memset(w,0,Kw);
  memset(w16,0,Kw*sizeof(int16_t));

864
  for (k=0; k<E; k++) {
865 866 867 868 869 870 871 872


    while(dummy_w[ind] == LTE_NULL) {
#ifdef RM_DEBUG_CC
      nulled++;
      printf("RM_RX : ind %d, NULL\n",ind);
#endif
      ind++;
873

874
      if (ind==Kw)
875
        ind=0;
876
    }
877

878 879 880 881 882 883
    /*
    if (w[ind] != 0)
      printf("repetition %d (%d,%d,%d)\n",ind,rvidx,E,Ncb);
    */
    // Maximum-ratio combining of repeated bits and retransmissions
#ifdef RM_DEBUG_CC
884
    printf("RM_RX_CC k %d (%d) ind: %d (%d)\n",k,soft_input[k],ind,w16[ind]);
885 886 887
#endif


888
    w16[ind] += soft_input[k];
889

890 891 892 893 894 895
    ind++;

    if (ind==Kw) {
      ind=0;
      acc++;
    }
896
  }
897

898
  // rescale
899
  for (ind=0; ind<Kw; ind++) {
900 901 902 903 904 905 906 907
    //    w16[ind]=(w16[ind]/acc);
    if (w16[ind]>7)
      w[ind]=7;
    else if (w16[ind]<-8)
      w[ind]=-8;
    else
      w[ind]=(int8_t)w16[ind];
  }
908

909 910 911 912 913 914 915 916 917
#ifdef RM_DEBUG_CC

  printf("Nulled %d\n",nulled);
#endif
}


#ifdef MAIN

918 919
void main()
{
920 921 922 923 924 925 926 927 928
  uint8_t d[96+3+(3*6144)];
  uint8_t w[3*6144],e[12*6144];
  uint32_t RTC,G,rvidx;
  uint32_t nb_rb=6;
  uint32_t mod_order = 4;
  uint32_t first_dlsch_symbol = 2;
  uint32_t i;

  G = ( nb_rb * (12 * mod_order) * (12-first_dlsch_symbol-3)) ;//( nb_rb * (12 * mod_order) * (14-first_dlsch_symbol-3)) :
929

930
  // initialize 96 first positions to "LTE_NULL"
931
  for (i=0; i<96; i++)
932 933 934
    d[i]=LTE_NULL;

  RTC = sub_block_interleaving_turbo(4+(192*8), &d[96], w);
935 936

  for (rvidx=0; rvidx<4; rvidx++) {
937
    lte_rate_matching_turbo(RTC,
938 939 940 941 942 943 944 945 946 947 948 949 950
                            G,
                            w,
                            e,
                            1,           //C
                            1827072,     //Nsoft,
                            8,           //Mdlharq,
                            1,           //Kmimo,
                            rvidx,       //rvidx,
                            mod_order,   //Qm,
                            1,           //Nl,
                            0            //r
                           );
  }
951 952 953 954
}

#endif