lte_rate_matching.c 20.8 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
/* file: lte_rate_matching.c
   purpose: Procedures for rate matching/interleaving for LTE (turbo-coded transport channels) (TX/RX)
   author: raymond.knopp@eurecom.fr
32
   date: 21.10.2009
33
34
35
36
37
*/
#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#endif
38
#include "PHY/defs.h"
39
#include "assertions.h"
40
41
42

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

gauthier's avatar
gauthier committed
43
44
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};
45
46
47
48
49
50
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
51
52
53

uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
{
54
55

  uint32_t RTC = (D>>5), ND, ND3;
knopp's avatar
knopp committed
56
  uint32_t row,col,Kpi;
57
  uint32_t index3,k,k2;
58
#ifdef RM_DEBUG
59
  uint32_t nulled=0;
60
#endif
61
62
63
64
  uint8_t *d1,*d2,*d3;

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

66
67
68
  Kpi = (RTC<<5);
  //  Kpi3 = Kpi*3;
  ND = Kpi - D;
69
#ifdef RM_DEBUG
70
71
  printf("sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3);
  printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND);
72
#endif
73
74
75
76
  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];
77
78
  k=0;
  k2=0;
79
80
81
82
  d1 = d-ND3;
  d2 = d1+1;
  d3 = d1+5;

83
  for (col=0; col<32; col++) {
84
85
86
87
#ifdef RM_DEBUG
    printf("Col %d\n",col);
#endif
    index3 = bitrev_x3[col];//3*index;
88
89

    for (row=0; row<RTC; row++) {
90
91
92

      w[k]            =  d1[index3];//d[index3-ND3];
      w[Kpi+k2]       =  d2[index3];//d[index3-ND3+1];
93
      w[Kpi+1+k2]     =  d3[index3];//d[index3-ND3+5];
94
95
96
97


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

99
      if (w[k]== LTE_NULL)
100
101
        nulled++;

102
      if (w[Kpi+(k<<1)] ==LTE_NULL)
103
104
        nulled++;

105
      if (w[Kpi+1+(k<<1)] ==LTE_NULL)
106
107
        nulled++;

108
109
#endif
      index3+=96;
knopp's avatar
knopp committed
110
      k++;k2+=2;
111
    }
112
113
114
115
  }

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

117
#ifdef RM_DEBUG
118

119
120
121
122
  if (ND>0) {
    printf("RM_TX: Nulled last component in pos %d\n",Kpi-1+k2);
    nulled++;
  }
123

124
125
126
127
128
129
  printf("RM_TX: Nulled %d\n",nulled);
#endif
  return(RTC);
}


130
131
uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
{
132
133
134
135
136
137
138
139
140
141

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

143
144
145
146
147
148
149
150
151
152
  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;
153
154

  for (col=0; col<32; col++) {
155
156
157
158
159
#ifdef RM_DEBUG_CC
    printf("Col %d\n",col);
#endif
    index = bitrev_cc[col];
    index3 = 3*index;
160
161

    for (row=0; row<RCC; row++) {
162
163
      w[k]          =  d[(int32_t)index3-(int32_t)ND3];
      w[Kpi+k]     =   d[(int32_t)index3-(int32_t)ND3+1];
164
      w[(Kpi<<1)+k] =  d[(int32_t)index3-(int32_t)ND3+2];
165
166
#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]);
167

168
      if (w[k]== LTE_NULL)
169
170
        nulled++;

171
      if (w[Kpi+k] ==LTE_NULL)
172
173
        nulled++;

174
      if (w[(Kpi<<1)+k] ==LTE_NULL)
175
176
        nulled++;

177
178
179
180
#endif
      index3+=96;
      index+=32;
      k++;
181
    }
182
  }
183

184
185
186
187
188
189
#ifdef RM_DEBUG_CC
  printf("RM_TX: Nulled %d\n",nulled);
#endif
  return(RCC);
}

190
191
void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w)
{
192
193
194
195
196
197
198
199

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

201
202
203
204
205
206
207
208
209
210
  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
211
212
  k=0;
  k2=0;
213
214
215
216
  d1 = d-ND3;
  d2 = d1+1;
  d3 = d1+5;

217
  for (col=0; col<32; col++) {
218
219
220
221
222
#ifdef RM_DEBUG2
    printf("Col %d\n",col);
#endif
    index = bitrev[col];
    index3 = bitrev_x3[col];//3*index;
223
224

    for (row=0; row<RTC; row++) {
225
226

      d1[index3]   = w[k];
227
228
      d2[index3]   = w[Kpi+k2];
      d3[index3]   = w[Kpi+1+k2];
229
230
      index3+=96;
      index+=32;
231
232
233
234
      k++;
      k2++;
      k2++;
    }
235
  }
236
237
238

  //  if (ND>0)
  //    d[2] = LTE_NULL;//d[(3*D)+2];
239
240
241

}

242
243
void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w)
{
244
245
246
247
248
249
250
251
252
253
254

  //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++;
255

256
257
258
259
260
261
262
263
264
265
  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;
266
267

  for (col=0; col<32; col++) {
268
269
270
271
272
#ifdef RM_DEBUG2
    printf("Col %d\n",col);
#endif
    index = bitrev_cc[col];
    index3 = 3*index;
273
274

    for (row=0; row<RCC; row++) {
275
276

      d[index3-ND3]   = w[k];
277
278
      d[index3-ND3+1] = w[Kpi+k];
      d[index3-ND3+2] = w[(Kpi<<1)+k];
279
280
281
282
283
284
#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++;
285
    }
286
287
288
289
  }

}

290
291
uint32_t generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F)
{
292
293
294
295
296
297
298
299
300
301
302

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

304
305
306
307
308
309
310
  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
311
312


313
314
315
316
317
318
  k=0;
  k2=0;
  wKpi = &w[Kpi];
  wKpi1 = &w[Kpi+1];
  wKpi2 = &w[Kpi+2];
  wKpi4 = &w[Kpi+4];
319
320

  for (col=0; col<32; col++) {
321
322
323
324
#ifdef RM_DEBUG
    printf("Col %d\n",col);
#endif
    index = bitrev[col];
325

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
    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
    }
342

343
344
345
346
347
348
349
350
351
352
353
354
355
356
    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
    }
357

358
359
360
361
362
363
364
#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;
  }

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

369
#ifdef RM_DEBUG
370

371
372
373
374
  if (ND>0) {
    nulled++;
    printf("dummy_w: Nulled final position %d\n",(3*Kpi)-1);
  }
375

376
377
378
379
380
  printf("Nulled = %d\n",nulled);
#endif
  return(RTC);
}

381
382
uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
{
383
384
385

  uint32_t RCC = (D>>5), ND;
  uint32_t col,Kpi,index;
gauthier's avatar
gauthier committed
386
  int32_t k;
387
388
389
390
391
392
#ifdef RM_DEBUG_CC
  uint32_t nulled=0;
#endif

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

394
395
396
397
398
399
400
401
402
403
404
405
  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;

406
  for (col=0; col<32; col++) {
407
408
409
410
#ifdef RM_DEBUG_CC
    printf("Col %d\n",col);
#endif
    index = bitrev_cc[col];
411

412
413
414
415
416
417
418
419
    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
    }
420

421
422
423
424
425
426
    /*
    //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;
427
    #ifdef RM_DEBUG
428
      nulled+=3;
429
    #endif
430
431
432
433
434
    }
    if (index+64<ND) {
      w[k+2]          = LTE_NULL;
      w[Kpi+2+k]      = LTE_NULL;
      w[(Kpi<<1)+2+k] = LTE_NULL;
435
    #ifdef RM_DEBUG
436
      nulled+=3;
437
    #endif
438
439
440
441
442
    }


    if ((index+1)<ND) {
      w[Kpi+1+(k<<1)] =  LTE_NULL;
443
    #ifdef RM_DEBUG
444
      nulled+=1;
445
    #endif
446
    }
447
    */
448
449
450
451
452
453
454
455
456
457
458
459
460
461
#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,
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
                                 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,
                                 uint8_t nb_rb,
                                 uint8_t m)
{


478
479
480
481
  uint32_t Nir,Ncb,Gp,GpmodC,E,Ncbmod,ind,k;
  //  int cnt=0;
  uint8_t *e2;
#ifdef RM_DEBUG_TX
482
  int code_block,round;
483
484
485
486
487
488
489
490
491
492
  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
493

494
495
496
497
498
499
500
501
  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
  }
502
#ifdef RM_DEBUG_TX
503
504
505
506
507
508

  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));
509
      }
510
511
512
513
  } 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");
514
  }
515

516
#endif
517

518
519
520
  // if (rvidx==3)
  //  for (cnt=0;cnt<Ncb;cnt++)
  //    counter_buffer[rvidx][cnt]=0;
knopp's avatar
knopp committed
521
522
  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));
523
  
524

525
526
527
528
  Gp = G/Nl/Qm;
  GpmodC = Gp%C;

#ifdef RM_DEBUG
529
  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);
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
#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

545
546
  //e2=e+(r*E);
  e2 = e;
547

548
549
  k=0;

550
  for (; (ind<Ncb)&&(k<E); ind++) {
551
    //    e2[k]=w[ind];
552
553
554
#ifdef RM_DEBUG_TX
    printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
#endif
555

556
    if (w[ind] != LTE_NULL) e2[k++]=w[ind];
557
  }
558

559
  while(k<E) {
560
    for (ind=0; (ind<Ncb)&&(k<E); ind++) {
561
      //      e2[k] = w[ind];
562
#ifdef RM_DEBUG_TX
563
      printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
564
#endif
565

566
      if (w[ind] != LTE_NULL) e2[k++]=w[ind];
567
568
    }
  }
569
570

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

573
574

    while(w[ind] == LTE_NULL) {
575
  #ifdef RM_DEBUG_TX
576
577
      printf("RM_tx : ind %d, NULL\n",ind);
      nulled++;
578
  #endif
579
580
      ind++;
      if (ind==Ncb)
581
  ind=0;
582
583
584
585
586
    }

    e2[k] = w[ind];
    //    printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
    //    cnt = cnt+1;
587
  #ifdef RM_DEBUG_TX
588
589
590
591
    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]);
592
  #endif
593
594
595
596
    ind++;
    if (ind==Ncb)
      ind=0;
  }
597
598

  #ifdef RM_DEBUG_TX
599
600
601
  if (rvidx==3){
    for(cnt=0;cnt<Ncb;cnt++)
      {
602
603
604
605
606
607
  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]
    );
608
609
    }
    fclose(counter_fd);
610

611
  }
612
613


614
615
616
617
618
619
620
621
622
623
624
625
   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++;
   }

626
627
628
629
630
  printf("zeroed %d\n",zeroed);
  printf("oned %d\n",oned);
  printf("twoed %d\n",twoed);
  printf("threed %d\n",threed);

631
  printf("nulled %d\n",nulled);
632
633
634

  #endif
  */
635
636
  return(E);
}
637

638
639

uint32_t lte_rate_matching_cc(uint32_t RCC,
640
641
642
643
644
                              uint16_t E,
                              uint8_t *w,
                              uint8_t *e)
{

645
646
647

  uint32_t ind=0,k;

gauthier's avatar
gauthier committed
648
  uint16_t Kw = 3*(RCC<<5);
649
650
651
652
653
654
655

#ifdef RM_DEBUG_CC
  uint32_t nulled=0;

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

656
  for (k=0; k<E; k++) {
657
658
659
660
661
662
663
664
665


    while(w[ind] == LTE_NULL) {

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

667
      if (ind==Kw)
668
        ind=0;
669
670
671
672
673
    }


    e[k] = w[ind];
#ifdef RM_DEBUG_CC
674
    //    printf("k %d ind %d, w %c(%d)\n",k,ind,w[ind],w[ind]);
675
676
677
    printf("RM_TX_CC %d Ind: %d (%d)\n",k,ind,e[k]);
#endif
    ind++;
678

679
680
681
    if (ind==Kw)
      ind=0;
  }
682

683
684
685
686
687
688
689
690
#ifdef RM_DEBUG_CC
  printf("nulled %d\n",nulled);
#endif
  return(E);
}


int lte_rate_matching_turbo_rx(uint32_t RTC,
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
                               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)
{


708
709
  uint32_t Nir,Ncb,Gp,GpmodC,E,Ncbmod,ind,k;
  int16_t *soft_input2;
710
  //   int32_t w_tmp;
711
712
713
#ifdef RM_DEBUG
  int nulled=0;
#endif
714

715
  if (Kmimo==0 || C==0 || Qm==0 || Nl==0) {
716
    printf("lte_rate_matching.c: invalid parameters (Kmimo %d, Mdlharq %d, C %d, Qm %d, Nl %d\n",
717
        Kmimo,Mdlharq,C,Qm,Nl);
718
719
720
    return(-1);
  }

721
722
723
724
725
726
727
728
  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);
  }
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749

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

knopp's avatar
   
knopp committed
751
  soft_input2 = soft_input;// + (r*E);
752
753
  k=0;

754
755
756
  for (; (ind<Ncb)&&(k<E); ind++) {
    if (dummy_w[ind] != LTE_NULL) {
      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;
gauthier's avatar
gauthier committed
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