dlsch_decoding.c 29.1 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 25 26 27 28 29 30 31 32 33
/*! \file PHY/LTE_TRANSPORT/dlsch_decoding.c
* \brief Top-level routines for decoding  Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/

//#include "defs.h"
34 35 36 37
#include "PHY/defs_UE.h"
#include "PHY/CODING/coding_extern.h"
#include "SCHED/sched_common_extern.h"
#include "SIMULATION/TOOLS/sim.h"
38
#include "common/utils/LOG/vcd_signal_dumper.h"
39
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
40
//#define DEBUG_DLSCH_DECODING
41
//#define UE_DEBUG_TRACE 1
42

frtabu's avatar
frtabu committed
43
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) {
44 45 46
  int i,r;

  if (dlsch) {
47
    for (i=0; i<dlsch->Mdlharq; i++) {
48
      if (dlsch->harq_processes[i]) {
49 50 51 52 53 54
        if (dlsch->harq_processes[i]->b) {
          free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
          dlsch->harq_processes[i]->b = NULL;
        }

        for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) {
55 56 57
          free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
          dlsch->harq_processes[i]->c[r] = NULL;
        }
58 59 60 61 62 63 64 65 66

        for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
          if (dlsch->harq_processes[i]->d[r]) {
            free16(dlsch->harq_processes[i]->d[r],((3*8*6144)+12+96)*sizeof(short));
            dlsch->harq_processes[i]->d[r] = NULL;
          }

        free16(dlsch->harq_processes[i],sizeof(LTE_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
67 68
      }
    }
69 70

    free16(dlsch,sizeof(LTE_UE_DLSCH_t));
71 72 73
  }
}

frtabu's avatar
frtabu committed
74
LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag) {
75 76 77
  LTE_UE_DLSCH_t *dlsch;
  uint8_t exit_flag = 0,i,r;
  unsigned char bw_scaling =1;
78 79

  switch (N_RB_DL) {
frtabu's avatar
frtabu committed
80
    case 6:
81
      bw_scaling =4;
frtabu's avatar
frtabu committed
82
      break;
83

frtabu's avatar
frtabu committed
84 85 86
    case 25:
      bw_scaling =4;
      break;
87

frtabu's avatar
frtabu committed
88 89 90
    case 50:
      bw_scaling =2;
      break;
91

frtabu's avatar
frtabu committed
92 93 94
    default:
      bw_scaling =1;
      break;
95
  }
96

97
  dlsch = (LTE_UE_DLSCH_t *)malloc16(sizeof(LTE_UE_DLSCH_t));
98

99
  if (dlsch) {
100
    memset(dlsch,0,sizeof(LTE_UE_DLSCH_t));
101 102
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
103
    dlsch->Nsoft = Nsoft;
104 105
    dlsch->max_turbo_iterations = max_turbo_iterations;

106
    for (i=0; i<Mdlharq; i++) {
107
      //      printf("new_ue_dlsch: Harq process %d\n",i);
108
      dlsch->harq_processes[i] = (LTE_DL_UE_HARQ_t *)malloc16(sizeof(LTE_DL_UE_HARQ_t));
109

110
      if (dlsch->harq_processes[i]) {
111 112
        memset(dlsch->harq_processes[i],0,sizeof(LTE_DL_UE_HARQ_t));
        dlsch->harq_processes[i]->first_tx=1;
frtabu's avatar
frtabu committed
113
        dlsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
114 115 116 117 118 119 120 121

        if (dlsch->harq_processes[i]->b)
          memset(dlsch->harq_processes[i]->b,0,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
          for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
frtabu's avatar
frtabu committed
122
            dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768);
123 124 125 126 127 128

            if (dlsch->harq_processes[i]->c[r])
              memset(dlsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+ 768);
            else
              exit_flag=2;

frtabu's avatar
frtabu committed
129
            dlsch->harq_processes[i]->d[r] = (short *)malloc16(((3*8*6144)+12+96)*sizeof(short));
130 131 132 133 134 135 136 137 138

            if (dlsch->harq_processes[i]->d[r])
              memset(dlsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short));
            else
              exit_flag=2;
          }
        }
      } else {
        exit_flag=1;
139 140 141 142 143 144
      }
    }

    if (exit_flag==0)
      return(dlsch);
  }
145

146
  printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag);
147 148 149 150 151 152 153 154 155
  free_ue_dlsch(dlsch);
  return(NULL);
}

uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
                         short *dlsch_llr,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         LTE_UE_DLSCH_t *dlsch,
                         LTE_DL_UE_HARQ_t *harq_process,
156
                         uint32_t frame,
157 158 159
                         uint8_t subframe,
                         uint8_t harq_pid,
                         uint8_t is_crnti,
frtabu's avatar
frtabu committed
160
                         uint8_t llr8_flag) {
gabrielC's avatar
gabrielC committed
161
#if UE_TIMING_TRACE
162 163 164
  time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
  time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
  time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
gabrielC's avatar
gabrielC committed
165
#endif
166 167 168 169 170 171 172 173
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
  //  uint8_t dummy_channel_output[(3*8*block_length)+12];
  short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0;
  uint8_t crc_type;
#ifdef DEBUG_DLSCH_DECODING
174
  uint16_t i;
175
#endif
176 177
  //#ifdef __AVX2__
#if 0
178 179
  int Kr_last,skipped_last=0;
  uint8_t (*tc_2cw)(int16_t *y,
frtabu's avatar
frtabu committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
                    int16_t *y2,
                    uint8_t *,
                    uint8_t *,
                    uint16_t,
                    uint16_t,
                    uint16_t,
                    uint8_t,
                    uint8_t,
                    uint8_t,
                    time_stats_t *,
                    time_stats_t *,
                    time_stats_t *,
                    time_stats_t *,
                    time_stats_t *,
                    time_stats_t *,
                    time_stats_t *);
#endif
  decoder_if_t *tc;
198

199
  if (!dlsch_llr) {
200
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
201 202 203 204
    return(dlsch->max_turbo_iterations);
  }

  if (!harq_process) {
205
    printf("dlsch_decoding.c: NULL harq_process pointer\n");
206
    return(dlsch->max_turbo_iterations);
207 208 209
  }

  if (!frame_parms) {
210
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
211
    return(dlsch->max_turbo_iterations);
212
  }
213

214
  if (subframe>9) {
215
    printf("dlsch_decoding.c: Illegal subframe index %d\n",subframe);
216
    return(dlsch->max_turbo_iterations);
217 218
  }

219
  if (dlsch->harq_ack[subframe].ack != 2) {
gabrielC's avatar
gabrielC committed
220
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
frtabu's avatar
frtabu committed
221
          phy_vars_ue->Mod_id, subframe, dlsch->harq_ack[subframe].ack);
222 223
  }

224
  if (llr8_flag == 0) {
225
    tc = decoder16;
frtabu's avatar
frtabu committed
226
  } else {
bruno mongazon's avatar
bruno mongazon committed
227
    AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n",
frtabu's avatar
frtabu committed
228
                 harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
bruno mongazon's avatar
bruno mongazon committed
229
    tc = decoder8;
230 231
  }

232 233 234
  //  nb_rb = dlsch->nb_rb;
  /*
  if (nb_rb > frame_parms->N_RB_DL) {
235
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
236 237
    return(max_turbo_iterations);
    }*/
238
  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
239
  if (harq_pid >= 8) {
240
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
241 242 243
    return(max_turbo_iterations);
  }
  */
244
  harq_process->trials[harq_process->round]++;
245 246 247 248 249
  A = harq_process->TBS; //2072 for QPSK 1/3
  ret = dlsch->max_turbo_iterations;
  G = harq_process->G;
  //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);

250
  //  printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
251

252
  if (harq_process->round == 0) {
253 254 255
    // This is a new packet, so compute quantities regarding segmentation
    harq_process->B = A+24;
    lte_segmentation(NULL,
256 257 258 259 260 261 262 263
                     NULL,
                     harq_process->B,
                     &harq_process->C,
                     &harq_process->Cplus,
                     &harq_process->Cminus,
                     &harq_process->Kplus,
                     &harq_process->Kminus,
                     &harq_process->F);
264 265
    //  CLEAR LLR's HERE for first packet in process
  }
266

267 268
  /*
  else {
269
    printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
270 271 272 273 274
    return(max_turbo_iterations);
  }
  */
  err_flag = 0;
  r_offset = 0;
275 276 277
  unsigned char bw_scaling =1;

  switch (frame_parms->N_RB_DL) {
frtabu's avatar
frtabu committed
278
    case 6:
279
      bw_scaling =4;
frtabu's avatar
frtabu committed
280
      break;
281

frtabu's avatar
frtabu committed
282 283 284
    case 25:
      bw_scaling =4;
      break;
285

frtabu's avatar
frtabu committed
286 287 288
    case 50:
      bw_scaling =2;
      break;
289

frtabu's avatar
frtabu committed
290 291 292
    default:
      bw_scaling =1;
      break;
293 294
  }

295
  if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) {
296 297 298
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling);
    return((1+dlsch->max_turbo_iterations));
  }
frtabu's avatar
frtabu committed
299

300 301 302
#ifdef DEBUG_DLSCH_DECODING
  printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
#endif
hbilel's avatar
hbilel committed
303 304
  opp_enabled=1;

305
  for (r=0; r<harq_process->C; r++) {
306 307 308 309 310
    // Get Turbo interleaver parameters
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;
311

312
    Kr_bytes = Kr>>3;
gabrielC's avatar
gabrielC committed
313
#if UE_TIMING_TRACE
314
    start_meas(dlsch_rate_unmatching_stats);
gabrielC's avatar
gabrielC committed
315
#endif
316
    memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
317
    harq_process->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
frtabu's avatar
frtabu committed
318
                                            (uint8_t *) &dummy_w[r][0],
319 320
                                            (r==0) ? harq_process->F : 0);
#ifdef DEBUG_DLSCH_DECODING
hbilel's avatar
hbilel committed
321
    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
322 323 324
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
325
          harq_process->Qm,
326 327 328 329 330
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
#endif
331 332 333
#ifdef DEBUG_DLSCH_DECODING
    printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
frtabu's avatar
frtabu committed
334

335
    if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
336 337
                                   G,
                                   harq_process->w[r],
frtabu's avatar
frtabu committed
338
                                   (uint8_t *)&dummy_w[r][0],
339 340
                                   dlsch_llr+r_offset,
                                   harq_process->C,
341
                                   dlsch->Nsoft,
342 343 344 345
                                   dlsch->Mdlharq,
                                   dlsch->Kmimo,
                                   harq_process->rvidx,
                                   (harq_process->round==0)?1:0,
346
                                   harq_process->Qm,
347 348 349
                                   harq_process->Nl,
                                   r,
                                   &E)==-1) {
gabrielC's avatar
gabrielC committed
350
#if UE_TIMING_TRACE
351
      stop_meas(dlsch_rate_unmatching_stats);
gabrielC's avatar
gabrielC committed
352
#endif
353
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
354
      return(dlsch->max_turbo_iterations);
frtabu's avatar
frtabu committed
355
    } else {
gabrielC's avatar
gabrielC committed
356
#if UE_TIMING_TRACE
357
      stop_meas(dlsch_rate_unmatching_stats);
gabrielC's avatar
gabrielC committed
358 359
#endif
    }
360

frtabu's avatar
frtabu committed
361
    r_offset += E;
362
    /*
363
    printf("Subblock deinterleaving, d %p w %p\n",
364 365
     harq_process->d[r],
     harq_process->w);
366
    */
gabrielC's avatar
gabrielC committed
367
#if UE_TIMING_TRACE
368
    start_meas(dlsch_deinterleaving_stats);
gabrielC's avatar
gabrielC committed
369
#endif
370 371 372
    sub_block_deinterleaving_turbo(4+Kr,
                                   &harq_process->d[r][96],
                                   harq_process->w[r]);
gabrielC's avatar
gabrielC committed
373
#if UE_TIMING_TRACE
374
    stop_meas(dlsch_deinterleaving_stats);
gabrielC's avatar
gabrielC committed
375
#endif
376
#ifdef DEBUG_DLSCH_DECODING
377 378
    /*
    if (r==0) {
bruno mongazon's avatar
bruno mongazon committed
379 380
              LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0);
              LOG_M("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
381
    }
382

383
    printf("decoder input(segment %d) :",r);
384
    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
385 386
      printf("%d : %d\n",i,harq_process->d[r][96+i]);
      printf("\n");*/
387
#endif
388
    //    printf("Clearing c, %p\n",harq_process->c[r]);
389
    memset(harq_process->c[r],0,Kr_bytes);
390

391
    //    printf("done\n");
392
    if (harq_process->C == 1)
393
      crc_type = CRC24_A;
394
    else
395 396
      crc_type = CRC24_B;

397
    /*
398
    printf("decoder input(segment %d)\n",r);
399
    for (i=0;i<(3*8*Kr_bytes)+12;i++)
400 401
      if ((harq_process->d[r][96+i]>7) ||
    (harq_process->d[r][96+i] < -8))
402 403
    printf("%d : %d\n",i,harq_process->d[r][96+i]);
    printf("\n");
404
    */
405 406
    //#ifndef __AVX2__
#if 1
frtabu's avatar
frtabu committed
407

408
    if (err_flag == 0) {
frtabu's avatar
frtabu committed
409 410 411 412 413 414 415 416 417 418
      /*
              LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
                                  Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
                                  harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations);
      */
      if (llr8_flag) {
        AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
                     Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
      }

gabrielC's avatar
gabrielC committed
419
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
420
      start_meas(dlsch_turbo_decoding_stats);
gabrielC's avatar
gabrielC committed
421
#endif
422
      LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
423
      ret = tc
424
            (&harq_process->d[r][96],
425
             NULL,
426
             harq_process->c[r],
427
             NULL,
428 429 430 431 432 433 434 435 436 437 438
             Kr,
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
gabrielC's avatar
gabrielC committed
439
#if UE_TIMING_TRACE
440
      stop_meas(dlsch_turbo_decoding_stats);
gabrielC's avatar
gabrielC committed
441
#endif
442
    }
frtabu's avatar
frtabu committed
443

444 445
#else

frtabu's avatar
frtabu committed
446 447
    if ((harq_process->C == 1) ||
        ((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments
gabrielC's avatar
gabrielC committed
448
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
449
      start_meas(dlsch_turbo_decoding_stats);
gabrielC's avatar
gabrielC committed
450
#endif
451 452 453 454 455 456 457 458 459 460 461 462 463 464
      ret = tc
            (&harq_process->d[r][96],
             harq_process->c[r],
             Kr,
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
frtabu's avatar
frtabu committed
465
#if UE_TIMING_TRACE
466
      stop_meas(dlsch_turbo_decoding_stats);
gabrielC's avatar
gabrielC committed
467
#endif
468 469
      //      printf("single decode, exit\n");
      //      exit(-1);
frtabu's avatar
frtabu committed
470 471
    } else {
      // we can merge code segments
472
      if ((skipped_last == 0) && (r<harq_process->C-1)) {
frtabu's avatar
frtabu committed
473 474 475 476
        skipped_last = 1;
        Kr_last = Kr;
      } else {
        skipped_last=0;
477

frtabu's avatar
frtabu committed
478
        if (Kr_last == Kr) { // decode 2 code segments with AVX2 version
479
#ifdef DEBUG_DLSCH_DECODING
frtabu's avatar
frtabu committed
480
          printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]);
481
#endif
gabrielC's avatar
gabrielC committed
482
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
483
          start_meas(dlsch_turbo_decoding_stats);
gabrielC's avatar
gabrielC committed
484
#endif
485
#ifdef DEBUG_DLSCH_DECODING
frtabu's avatar
frtabu committed
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
          printf("double decoding segments %d,%d (%p,%p)\n",r-1,r,&harq_process->d[r-1][96],&harq_process->d[r][96]);
#endif
          ret = tc_2cw
                (&harq_process->d[r-1][96],
                 &harq_process->d[r][96],
                 harq_process->c[r-1],
                 harq_process->c[r],
                 Kr,
                 dlsch->max_turbo_iterations,
                 crc_type,
                 (r==0) ? harq_process->F : 0,
                 &phy_vars_ue->dlsch_tc_init_stats,
                 &phy_vars_ue->dlsch_tc_alpha_stats,
                 &phy_vars_ue->dlsch_tc_beta_stats,
                 &phy_vars_ue->dlsch_tc_gamma_stats,
                 &phy_vars_ue->dlsch_tc_ext_stats,
                 &phy_vars_ue->dlsch_tc_intl1_stats,
                 &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
          /*
          ret = tc
                  (&harq_process->d[r-1][96],
                   harq_process->c[r-1],
                   Kr_last,
                   dlsch->max_turbo_iterations,
                   crc_type,
                   (r==0) ? harq_process->F : 0,
                   &phy_vars_ue->dlsch_tc_init_stats,
                   &phy_vars_ue->dlsch_tc_alpha_stats,
                   &phy_vars_ue->dlsch_tc_beta_stats,
                   &phy_vars_ue->dlsch_tc_gamma_stats,
                   &phy_vars_ue->dlsch_tc_ext_stats,
                   &phy_vars_ue->dlsch_tc_intl1_stats,
                   &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);

             exit(-1);*/
gabrielC's avatar
gabrielC committed
521
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
522
          stop_meas(dlsch_turbo_decoding_stats);
gabrielC's avatar
gabrielC committed
523
#endif
frtabu's avatar
frtabu committed
524
        } else { // Kr_last != Kr
gabrielC's avatar
gabrielC committed
525
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
          start_meas(dlsch_turbo_decoding_stats);
#endif
          ret = tc
                (&harq_process->d[r-1][96],
                 harq_process->c[r-1],
                 Kr_last,
                 dlsch->max_turbo_iterations,
                 crc_type,
                 (r==0) ? harq_process->F : 0,
                 &phy_vars_ue->dlsch_tc_init_stats,
                 &phy_vars_ue->dlsch_tc_alpha_stats,
                 &phy_vars_ue->dlsch_tc_beta_stats,
                 &phy_vars_ue->dlsch_tc_gamma_stats,
                 &phy_vars_ue->dlsch_tc_ext_stats,
                 &phy_vars_ue->dlsch_tc_intl1_stats,
                 &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
gabrielC's avatar
gabrielC committed
542
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
          stop_meas(dlsch_turbo_decoding_stats);
          start_meas(dlsch_turbo_decoding_stats);
#endif
          ret = tc
                (&harq_process->d[r][96],
                 harq_process->c[r],
                 Kr,
                 dlsch->max_turbo_iterations,
                 crc_type,
                 (r==0) ? harq_process->F : 0,
                 &phy_vars_ue->dlsch_tc_init_stats,
                 &phy_vars_ue->dlsch_tc_alpha_stats,
                 &phy_vars_ue->dlsch_tc_beta_stats,
                 &phy_vars_ue->dlsch_tc_gamma_stats,
                 &phy_vars_ue->dlsch_tc_ext_stats,
                 &phy_vars_ue->dlsch_tc_intl1_stats,
                 &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
gabrielC's avatar
gabrielC committed
560
#if UE_TIMING_TRACE
frtabu's avatar
frtabu committed
561 562 563 564 565 566 567
          stop_meas(dlsch_turbo_decoding_stats);
          /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
                    harq_process->C,
                    r,
                    dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
                    dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
                    dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
gabrielC's avatar
gabrielC committed
568
#endif
frtabu's avatar
frtabu committed
569
        }
570 571
      }
    }
572

frtabu's avatar
frtabu committed
573
#endif
574

575
    if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
576
      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
577 578
      err_flag = 1;
    }
579
  }
580

581 582
  int32_t frame_rx_prev = frame;
  int32_t subframe_rx_prev = subframe - 1;
frtabu's avatar
frtabu committed
583

584 585 586
  if (subframe_rx_prev < 0) {
    frame_rx_prev--;
    subframe_rx_prev += 10;
587
  }
frtabu's avatar
frtabu committed
588

589
  frame_rx_prev = frame_rx_prev%1024;
590 591

  if (err_flag == 1) {
gabrielC's avatar
gabrielC committed
592
#if UE_DEBUG_TRACE
593
    LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
frtabu's avatar
frtabu committed
594
          phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
gabrielC's avatar
gabrielC committed
595
#endif
596 597 598
    dlsch->harq_ack[subframe].ack = 0;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
599
    harq_process->errors[harq_process->round]++;
600
    harq_process->round++;
601

Raymond Knopp's avatar
Raymond Knopp committed
602
    //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
603 604
    if (harq_process->round >= dlsch->Mdlharq) {
      harq_process->status = SCH_IDLE;
hbilel's avatar
hbilel committed
605 606
      harq_process->round  = 0;
    }
frtabu's avatar
frtabu committed
607 608 609 610

    if(is_crnti) {
      LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
            phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
611
    }
612

613
    return((1+dlsch->max_turbo_iterations));
614
  } else {
gabrielC's avatar
gabrielC committed
615
#if UE_DEBUG_TRACE
frtabu's avatar
frtabu committed
616 617
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n",
          phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
gabrielC's avatar
gabrielC committed
618
#endif
619 620 621 622 623
    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
    dlsch->harq_ack[subframe].ack = 1;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
gabrielC's avatar
gabrielC committed
624
    //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
frtabu's avatar
frtabu committed
625
    //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
hbilel's avatar
hbilel committed
626

frtabu's avatar
frtabu committed
627 628
    if(is_crnti) {
      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
629
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
630

frtabu's avatar
frtabu committed
631
    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
632
  }
633

634 635
  // Reassembly of Transport block here
  offset = 0;
636 637

  /*
638 639 640
  printf("harq_pid %d\n",harq_pid);
  printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
  printf("C %d\n",harq_process->C);
641
  */
642
  for (r=0; r<harq_process->C; r++) {
643 644 645 646 647 648
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;

    Kr_bytes = Kr>>3;
649

650 651 652
    //    printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
    if (r==0) {
      memcpy(harq_process->b,
653 654
             &harq_process->c[0][(harq_process->F>>3)],
             Kr_bytes - (harq_process->F>>3)- ((harq_process->C>1)?3:0));
655
      offset = Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0);
656
      //            printf("copied %d bytes to b sequence (harq_pid %d)\n",
657
      //          Kr_bytes - (harq_process->F>>3),harq_pid);
658
      //          printf("b[0] = %x,c[%d] = %x\n",
659 660 661 662
      //      harq_process->b[0],
      //      harq_process->F>>3,
      //      harq_process->c[0][(harq_process->F>>3)]);
    } else {
663
      memcpy(harq_process->b+offset,
664 665
             harq_process->c[r],
             Kr_bytes- ((harq_process->C>1)?3:0));
666 667 668
      offset += (Kr_bytes - ((harq_process->C>1)?3:0));
    }
  }
669

670
  dlsch->last_iteration_cnt = ret;
671 672 673
  return(ret);
}

674
int dlsch_encoding_SIC(PHY_VARS_UE *ue,
frtabu's avatar
frtabu committed
675 676 677 678 679 680 681 682
                       unsigned char *a,
                       uint8_t num_pdcch_symbols,
                       LTE_eNB_DLSCH_t *dlsch,
                       int frame,
                       uint8_t subframe,
                       time_stats_t *rm_stats,
                       time_stats_t *te_stats,
                       time_stats_t *i_stats) {
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
  unsigned int G;
  unsigned int crc=1;
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti;
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
  unsigned int A;
  unsigned char mod_order;
  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
  //  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
  uint8_t beamforming_mode=0;
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
  A = dlsch->harq_processes[harq_pid]->TBS; //6228
  // printf("Encoder: A: %d\n",A);
  mod_order = dlsch->harq_processes[harq_pid]->Qm;

  if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
    beamforming_mode = 7;
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
    beamforming_mode = 8;
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
    beamforming_mode = 9;

frtabu's avatar
frtabu committed
705
  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
706 707 708 709

  //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
#ifdef DEBUG_DLSCH_CODING
frtabu's avatar
frtabu committed
710
    printf("SIC encoding thinks this is a new packet \n");
711 712 713 714 715 716 717 718 719 720 721
#endif
    /*
    int i;
    printf("dlsch (tx): \n");
    for (i=0;i<(A>>3);i++)
      printf("%02x.",a[i]);
    printf("\n");
    */
    // Add 24-bit crc (polynomial A) to payload
    crc = crc24a(a,
                 A)>>8;
frtabu's avatar
frtabu committed
722 723 724
    a[A>>3] = ((uint8_t *)&crc)[2];
    a[1+(A>>3)] = ((uint8_t *)&crc)[1];
    a[2+(A>>3)] = ((uint8_t *)&crc)[0];
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
    //    printf("CRC %x (A %d)\n",crc,A);
    dlsch->harq_processes[harq_pid]->B = A+24;
    //    dlsch->harq_processes[harq_pid]->b = a;
    memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);

    if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
                         dlsch->harq_processes[harq_pid]->c,
                         dlsch->harq_processes[harq_pid]->B,
                         &dlsch->harq_processes[harq_pid]->C,
                         &dlsch->harq_processes[harq_pid]->Cplus,
                         &dlsch->harq_processes[harq_pid]->Cminus,
                         &dlsch->harq_processes[harq_pid]->Kplus,
                         &dlsch->harq_processes[harq_pid]->Kminus,
                         &dlsch->harq_processes[harq_pid]->F)<0)
      return(-1);

    for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
      if (r<dlsch->harq_processes[harq_pid]->Cminus)
        Kr = dlsch->harq_processes[harq_pid]->Kminus;
      else
        Kr = dlsch->harq_processes[harq_pid]->Kplus;

      Kr_bytes = Kr>>3;
#ifdef DEBUG_DLSCH_CODING
749
      printf("Generating Code Segment %u (%u bits)\n",r,Kr);
750
      // generate codewords
frtabu's avatar
frtabu committed
751
      printf("bits_per_codeword (Kr)= %u, A %u\n",Kr,A);
752 753 754 755 756 757 758 759
      printf("N_RB = %d\n",nb_rb);
      printf("Ncp %d\n",frame_parms->Ncp);
      printf("mod_order %d\n",mod_order);
#endif
      start_meas(te_stats);
      encoder(dlsch->harq_processes[harq_pid]->c[r],
              Kr>>3,
              &dlsch->harq_processes[harq_pid]->d[r][96],
760
              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0
761 762 763 764 765
             );
      stop_meas(te_stats);
#ifdef DEBUG_DLSCH_CODING

      if (r==0)
bruno mongazon's avatar
bruno mongazon committed
766
        LOG_M("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782

#endif
      start_meas(i_stats);
      dlsch->harq_processes[harq_pid]->RTC[r] =
        sub_block_interleaving_turbo(4+(Kr_bytes*8),
                                     &dlsch->harq_processes[harq_pid]->d[r][96],
                                     dlsch->harq_processes[harq_pid]->w[r]);
      stop_meas(i_stats);
    }
  }

  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
  // outputs for each code segment, see Section 5.1.5 p.20

  for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
#ifdef DEBUG_DLSCH_CODING
frtabu's avatar
frtabu committed
783 784 785 786 787
    printf("Rate Matching, Code segment %u (coded bits (G) %u,unpunctured/repeated bits per code segment %u,mod_order %d, nb_rb %d)...\n",
           r,
           G,
           Kr*3,
           mod_order,nb_rb);
788 789 790 791 792 793 794 795
#endif
    start_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING
    printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                        G,  //G
                                        dlsch->harq_processes[harq_pid]->w[r],
laurent's avatar
laurent committed
796
                                        dlsch->harq_processes[harq_pid]->eDL+r_offset,
797 798 799 800 801 802 803 804 805 806 807 808 809 810
                                        dlsch->harq_processes[harq_pid]->C, // C
                                        dlsch->Nsoft,                    // Nsoft,
                                        dlsch->Mdlharq,
                                        dlsch->Kmimo,
                                        dlsch->harq_processes[harq_pid]->rvidx,
                                        dlsch->harq_processes[harq_pid]->Qm,
                                        dlsch->harq_processes[harq_pid]->Nl,
                                        r,
                                        nb_rb);
    //                                        m);                       // r
    stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING

    if (r==dlsch->harq_processes[harq_pid]->C-1)
bruno mongazon's avatar
bruno mongazon committed
811
      LOG_M("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
812 813 814 815 816 817 818

#endif
  }

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
  return(0);
}