dlsch_coding.c 36.7 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
Cedric Roux's avatar
Cedric Roux committed
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
 * 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
 */
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/*! \file PHY/LTE_TRANSPORT/dlsch_coding.c
* \brief Top-level routines for implementing 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 "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/defs.h"
39
#include "PHY/LTE_TRANSPORT/proto.h"
Cedric Roux's avatar
Cedric Roux committed
40
#include "SCHED/defs.h"
41
#include "defs.h"
42
#include "UTIL/LOG/vcd_signal_dumper.h"
43
44
#include "UTIL/LOG/log.h"
#include <syscall.h>
45
#include "targets/RT/USER/rt_wrapper.h"
46

47
//#define DEBUG_DLSCH_CODING
48
49
50
//#define DEBUG_DLSCH_FREE 1

/*
51
52
53
#define is_not_pilot(pilots,first_pilot,re) (pilots==0) || \
  ((pilots==1)&&(first_pilot==1)&&(((re>2)&&(re<6))||((re>8)&&(re<12)))) || \
  ((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \
54
55
*/
#define is_not_pilot(pilots,first_pilot,re) (1)
Wang Tsu-Han's avatar
Wang Tsu-Han committed
56
57
58
59
60
/*extern void thread_top_init(char *thread_name,
		     int affinity,
		     uint64_t runtime,
		     uint64_t deadline,
		     uint64_t period);*/
61

Wang Tsu-Han's avatar
Wang Tsu-Han committed
62
63
extern int codingw;

64
65
void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
{
66
  int i, r, aa, layer;
67
68

  if (dlsch) {
69
70
71
72
    for (layer=0; layer<4; layer++) {
      for (aa=0; aa<64; aa++) free16(dlsch->ue_spec_bf_weights[layer][aa], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
      free16(dlsch->ue_spec_bf_weights[layer], 64*sizeof(int32_t*));
    }
73
    for (i=0; i<dlsch->Mdlharq; i++) {
74
      if (dlsch->harq_processes[i]) {
75
76
77
78
79
80
81
82
83
        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++) {
          if (dlsch->harq_processes[i]->c[r]) {
            free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
            dlsch->harq_processes[i]->c[r] = NULL;
          }
84
          if (dlsch->harq_processes[i]->d[r]) {
85
            free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
86
87
            dlsch->harq_processes[i]->d[r] = NULL;
          }
88
89
90
	}
	free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
	dlsch->harq_processes[i] = NULL;
91
92
93
      }
    }
    free16(dlsch,sizeof(LTE_eNB_DLSCH_t));
94
    dlsch = NULL;
95
  }
96
97
}

98
LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms)
99
{
100
101

  LTE_eNB_DLSCH_t *dlsch;
102
103
  unsigned char exit_flag = 0,i,j,r,aa,layer;
  int re;
104
  unsigned char bw_scaling =1;
105
106
107

  switch (N_RB_DL) {
  case 6:
108
109
    bw_scaling =16;
    break;
110

111
112
113
  case 25:
    bw_scaling =4;
    break;
114
115

  case 50:
116
117
    bw_scaling =2;
    break;
118

119
120
121
122
  default:
    bw_scaling =1;
    break;
  }
123

124
  dlsch = (LTE_eNB_DLSCH_t *)malloc16(sizeof(LTE_eNB_DLSCH_t));
125

126
127
128
129
  if (dlsch) {
    bzero(dlsch,sizeof(LTE_eNB_DLSCH_t));
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
130
    dlsch->Mlimit = 8;
131
    dlsch->Nsoft = Nsoft;
132
    
133
    for (layer=0; layer<4; layer++) {
134
      dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
135
      
136
      for (aa=0; aa<64; aa++) {
137
138
139
140
141
142
	dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
	for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
	  dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
	}
      }
    }
143

144
145
    // NOTE: THIS HAS TO BE REVISED FOR RU, commenting to remove memory leak !!!!!
    /*
146
147
148
     dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
       dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
149

150
       }*/
151

152
    for (i=0; i<10; i++)
153
154
      dlsch->harq_ids[i] = Mdlharq;

155
    for (i=0; i<Mdlharq; i++) {
156
      dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
157
      LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
158
159
            MAX_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);

160
      if (dlsch->harq_processes[i]) {
161
162
163
164
165
166
167
        bzero(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
        //    dlsch->harq_processes[i]->first_tx=1;
        dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);

        if (dlsch->harq_processes[i]->b) {
          bzero(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
        } else {
168
          printf("Can't get b\n");
169
170
171
172
173
174
          exit_flag=1;
        }

        if (abstraction_flag==0) {
          for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
            // account for filler in first segment and CRCs for multiple segment case
175
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768);
176
            dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16((96+12+3+(3*6144)));
177
178
179
            if (dlsch->harq_processes[i]->c[r]) {
              bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
            } else {
180
              printf("Can't get c\n");
181
182
              exit_flag=2;
            }
183
            if (dlsch->harq_processes[i]->d[r]) {
184
              bzero(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
185
            } else {
186
              printf("Can't get d\n");
187
188
              exit_flag=2;
            }
189
          }
190
191
        }
      } else {
192
        printf("Can't get harq_p %d\n",i);
193
        exit_flag=3;
194
195
      }
    }
196

197
    if (exit_flag==0) {
198
199
200
      for (i=0; i<Mdlharq; i++) {
        dlsch->harq_processes[i]->round=0;

201
202
203
204
205
206
	for (j=0; j<96; j++)
	  for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
	    //      printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]);
	    if (dlsch->harq_processes[i]->d[r])
	      dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
	  }
207

208
      }
209

210
211
212
      return(dlsch);
    }
  }
213

214
215
  LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of  %ld\n",
	exit_flag, sizeof(LTE_eNB_DLSCH_t));
216
217
  free_eNB_dlsch(dlsch);
  return(NULL);
218
219


220
221
}

222
void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
223
{
224
225
226

  unsigned char Mdlharq;
  unsigned char i,j,r;
227

228
229
230
231
  if (dlsch) {
    Mdlharq = dlsch->Mdlharq;
    dlsch->rnti = 0;
    dlsch->active = 0;
232
    dlsch->harq_mask = 0;
233
234

    for (i=0; i<10; i++)
235
236
      dlsch->harq_ids[i] = Mdlharq;

237
    for (i=0; i<Mdlharq; i++) {
238
      if (dlsch->harq_processes[i]) {
239
240
241
242
        //  dlsch->harq_processes[i]->Ndi    = 0;
        dlsch->harq_processes[i]->status = 0;
        dlsch->harq_processes[i]->round  = 0;

243
244
245
246
	for (j=0; j<96; j++)
	  for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
	    if (dlsch->harq_processes[i]->d[r])
	      dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
247

248
249
250
251
252
      }
    }
  }
}

253

254
255


256
257
258
259
int dlsch_encoding_2threads0(te_params *tep) {

  LTE_eNB_DLSCH_t *dlsch          = tep->dlsch;
  unsigned int G                  = tep->G;
260
  unsigned char harq_pid          = tep->harq_pid;
Eurecom's avatar
Eurecom committed
261
262
  unsigned int total_worker       = tep->total_worker;
  unsigned int current_worker     = tep->current_worker;
263
264

  unsigned short iind;
265

266
267
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
268
  //  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
269
270


271
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN);
272
273
274

  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet

Eurecom's avatar
Eurecom committed
275
    for (r=(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*current_worker; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

      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;

      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      if (Kr_bytes<=64)
        iind = (Kr_bytes-5);
      else if (Kr_bytes <=128)
        iind = 59 + ((Kr_bytes-64)>>1);
      else if (Kr_bytes <= 256)
        iind = 91 + ((Kr_bytes-128)>>2);
      else if (Kr_bytes <= 768)
        iind = 123 + ((Kr_bytes-256)>>3);
      else {
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
        return(-1);
      }



300
301
302
303
304
305
306
      encoder(dlsch->harq_processes[harq_pid]->c[r],
              Kr>>3,
              &dlsch->harq_processes[harq_pid]->d[r][96],
              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
              f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
              f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
             );
307
308
309
310
311
312
313
314
315
316
317
      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]);
    }

  }

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

Eurecom's avatar
Eurecom committed
318
319
  for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
    if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)){
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
	  int Nl=dlsch->harq_processes[harq_pid]->Nl;
      int Qm=dlsch->harq_processes[harq_pid]->Qm;
      int C = dlsch->harq_processes[harq_pid]->C;
      int Gp = G/Nl/Qm;
      int GpmodC = Gp%C;
      if (r < (C-(GpmodC)))
	    r_offset += Nl*Qm * (Gp/C);
      else
	    r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
	}
	else{
      r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                          G,  //G
                                          dlsch->harq_processes[harq_pid]->w[r],
                                          dlsch->harq_processes[harq_pid]->e+r_offset,
                                          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
    }
  }

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT);

  return(0);
}

353

354
355
extern int oai_exit;
void *te_thread(void *param) {
356
357
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
358
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
359
  thread_top_init("te_thread",1,200000,250000,500000);
360
  pthread_setname_np( pthread_self(),"te processing");
361
362
  LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid));
  
363

Eurecom's avatar
Eurecom committed
364
  te_params *tep                 = (te_params *)param;
Eurecom's avatar
Eurecom committed
365
  
366
  //wait_sync("te_thread");
Eurecom's avatar
Eurecom committed
367
  
368
369
  while (!oai_exit) {

Eurecom's avatar
Eurecom committed
370
    if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
371
    if(oai_exit) break;
372

Eurecom's avatar
Eurecom committed
373
    dlsch_encoding_2threads0(tep);
374

Eurecom's avatar
Eurecom committed
375
    if (release_thread(&tep->mutex_te,&tep->instance_cnt_te,"te thread")<0) break;
376

Eurecom's avatar
Eurecom committed
377
    if (pthread_cond_signal(&tep->cond_te) != 0) {
378
379
380
381
      printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return(NULL);
    }
382
    /*if(opp_enabled == 1 && te_wakeup_stats0->diff_now>50*3000){
383
      print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr);
384
385
      printf("te_thread0 delay for waking up in frame_rx: %d  subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
    }*/
386
387
388
389
390
  }

  return(NULL);
}

391
392


393
394
395
396
397
398
399
400
int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
			    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,
Wang Tsu-Han's avatar
Wang Tsu-Han committed
401
				time_stats_t *te_wait_stats,
402
                time_stats_t *te_main_stats,
403
404
                time_stats_t *te_wakeup_stats0,
                time_stats_t *te_wakeup_stats1,
Eurecom's avatar
Eurecom committed
405
406
                time_stats_t *i_stats,
                int worker_num)
407
408
{

409
410
  //start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);

411
412
413
414
415
416
  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
  eNB_proc_t *proc = &eNB->proc;
  unsigned int G;
  unsigned int crc=1;
  unsigned short iind;

417
  unsigned char harq_pid = dlsch->harq_ids[subframe];
418
419
420
421
  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;
422
  //  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
423
424
425
426

  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
427
  mod_order = dlsch->harq_processes[harq_pid]->Qm;
428
  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,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
429
430
431

  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet

432
    start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
433
434
435
    // Add 24-bit crc (polynomial A) to payload
    crc = crc24a(a,
                 A)>>8;
Eurecom's avatar
Eurecom committed
436
    stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
437
438
439
440
441
442
    a[A>>3] = ((uint8_t*)&crc)[2];
    a[1+(A>>3)] = ((uint8_t*)&crc)[1];
    a[2+(A>>3)] = ((uint8_t*)&crc)[0];

    dlsch->harq_processes[harq_pid]->B = A+24;
    memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
Eurecom's avatar
Eurecom committed
443
    //stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
444

445
    start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
446
447
448
449
450
451
452
453
454
455
456
    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);

457
458
459
    stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
    
    start_meas(&eNB->dlsch_turbo_encoding_signal_stats);
Eurecom's avatar
Eurecom committed
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    for(int i=0;i<worker_num;i++)
    {
      proc->tep[i].eNB               = eNB;
      proc->tep[i].dlsch             = dlsch;
      proc->tep[i].G                 = G;
      proc->tep[i].harq_pid          = harq_pid;
      proc->tep[i].total_worker      = worker_num;
      proc->tep[i].current_worker    = i;
    
      pthread_mutex_lock( &proc->tep[i].mutex_te );
      if (proc->tep[i].instance_cnt_te==0) {
        printf("[eNB] TE thread busy\n");
        exit_fun("TE thread busy");
        pthread_mutex_unlock( &proc->tep[i].mutex_te );
        return(-1);
      }
476
      
Eurecom's avatar
Eurecom committed
477
478
479
480
481
482
483
484
485
486
      ++proc->tep[i].instance_cnt_te;
      
      // wakeup worker to do segments
      if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
        printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i);
        exit_fun( "ERROR pthread_cond_signal" );
        return (-1);
      }
      
      pthread_mutex_unlock( &proc->tep[i].mutex_te );
487
488
    }

489
    stop_meas(&eNB->dlsch_turbo_encoding_signal_stats);
490
    start_meas(te_main_stats);
Eurecom's avatar
Eurecom committed
491
    for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) {
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515

      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;

      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      if (Kr_bytes<=64)
        iind = (Kr_bytes-5);
      else if (Kr_bytes <=128)
        iind = 59 + ((Kr_bytes-64)>>1);
      else if (Kr_bytes <= 256)
        iind = 91 + ((Kr_bytes-128)>>2);
      else if (Kr_bytes <= 768)
        iind = 123 + ((Kr_bytes-256)>>3);
      else {
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
        return(-1);
      }


      start_meas(te_stats);
516
517
518
519
520
521
522
      encoder(dlsch->harq_processes[harq_pid]->c[r],
              Kr>>3,
              &dlsch->harq_processes[harq_pid]->d[r][96],
              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
              f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
              f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
             );
523
524
525
526
527
528
529
530
531
532
533
534
535
      stop_meas(te_stats);

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

  }
  else {

Eurecom's avatar
Eurecom committed
536
537
538
539
540
541
542
543
    for(int i=0;i<worker_num;i++)
    {
      proc->tep[i].eNB               = eNB;
      proc->tep[i].dlsch             = dlsch;
      proc->tep[i].G                 = G;
      proc->tep[i].total_worker      = worker_num;
      proc->tep[i].current_worker    = i;
      if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
544
545
546
        printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
        exit_fun( "ERROR pthread_cond_signal" );
        return (-1);
Eurecom's avatar
Eurecom committed
547
      }
548
    }
549
550
551
552
  }

  // 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
553
  for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
554
555

    // get information for E for the segments that are handled by the worker thread
Eurecom's avatar
Eurecom committed
556
    if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) {
557
      int Nl=dlsch->harq_processes[harq_pid]->Nl;
558
      int Qm=dlsch->harq_processes[harq_pid]->Qm;
559
560
561
562
563
564
565
566
567
      int C = dlsch->harq_processes[harq_pid]->C;
      int Gp = G/Nl/Qm;
      int GpmodC = Gp%C;
      if (r < (C-(GpmodC)))
	r_offset += Nl*Qm * (Gp/C);
      else
	r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
    }
    else  {
568
      start_meas(rm_stats);
569
570
571
572
573
574
575
576
577
      r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
					  G,  //G
					  dlsch->harq_processes[harq_pid]->w[r],
					  dlsch->harq_processes[harq_pid]->e+r_offset,
					  dlsch->harq_processes[harq_pid]->C, // C
					  dlsch->Nsoft,                    // Nsoft,
					  dlsch->Mdlharq,
					  dlsch->Kmimo,
					  dlsch->harq_processes[harq_pid]->rvidx,
578
					  dlsch->harq_processes[harq_pid]->Qm,
579
580
					  dlsch->harq_processes[harq_pid]->Nl,
					  r,
581
582
					  nb_rb);
      //					  m);                       // r
583
      stop_meas(rm_stats);
584
585
    }
  }
586
  stop_meas(te_main_stats);
587

Wang Tsu-Han's avatar
Wang Tsu-Han committed
588
  start_meas(te_wait_stats);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
  if(worker_num == 1)
  {
    wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
  }
  else if(worker_num == 2)
  {
    wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
    wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
  }
  else
  {
    wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
    wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
    wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2");
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
604
  stop_meas(te_wait_stats);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
605
606
  
  /*if(opp_enabled == 1 && te_wait_stats->diff_now>100*3000){
Wang Tsu-Han's avatar
Wang Tsu-Han committed
607
    print_meas_now(te_wait_stats,"coding_wait",stderr);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
608
609
	printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx);
  }*/
610

611
612
613
614
615

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);

  return(0);
}
616
617
618
619
620
621
622
623
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
		   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,
Wang Tsu-Han's avatar
Wang Tsu-Han committed
624
				   time_stats_t *te_wait_stats,
625
                   time_stats_t *te_main_stats,
626
627
                   time_stats_t *te_wakeup_stats0,
                   time_stats_t *te_wakeup_stats1,
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
                   time_stats_t *i_stats)
{
	int encoding_return = 0;
	unsigned int L,C,B;
	B = dlsch->harq_processes[dlsch->harq_ids[subframe]]->B;
	if(B<=6144)
	{
		L=0;
		C=1;
	}
	else
	{
		L=24;
		C = B/(6144-L);
		if((6144-L)*C < B)
		{
			C = C+1;
		}
	}
Wang Tsu-Han's avatar
Wang Tsu-Han committed
647
//LOG_I(PHY,"segmentation number C = %d\n", C);////////////********added
648

649
650
651
    if(C >= 8 && get_nprocs()>=16 && codingw)//one main three worker
    {
        encoding_return =
652
653
654
655
656
657
658
659
		dlsch_encoding_2threads(eNB,
				   a,
                   num_pdcch_symbols,
                   dlsch,
                   frame,
                   subframe,
                   rm_stats,
                   te_stats,
660
                   te_wait_stats,
661
                   te_main_stats,
662
663
                   te_wakeup_stats0,
                   te_wakeup_stats1,
Eurecom's avatar
Eurecom committed
664
665
                   i_stats,
                   3);
666
667
    }
    else if(C >= 6 && get_nprocs()>=8 && codingw)//one main two worker
Eurecom's avatar
Eurecom committed
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
    {
        encoding_return =
		dlsch_encoding_2threads(eNB,
				   a,
                   num_pdcch_symbols,
                   dlsch,
                   frame,
                   subframe,
                   rm_stats,
                   te_stats,
                   te_wait_stats,
                   te_main_stats,
                   te_wakeup_stats0,
                   te_wakeup_stats1,
                   i_stats,
                   2);
    }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
685
    else if(C >= 4 && get_nprocs()>=4 && codingw)//one main one worker
Eurecom's avatar
Eurecom committed
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
    {
        encoding_return =
		dlsch_encoding_2threads(eNB,
				   a,
                   num_pdcch_symbols,
                   dlsch,
                   frame,
                   subframe,
                   rm_stats,
                   te_stats,
                   te_wait_stats,
                   te_main_stats,
                   te_wakeup_stats0,
                   te_wakeup_stats1,
                   i_stats,
                   1);
    }
703
	else
Eurecom's avatar
Eurecom committed
704
	{
705
706
707
708
709
710
711
712
713
714
		encoding_return =
		dlsch_encoding(eNB,
				   a,
                   num_pdcch_symbols,
                   dlsch,
                   frame,
                   subframe,
                   rm_stats,
                   te_stats,
                   i_stats);
Eurecom's avatar
Eurecom committed
715
	}
716
717
718
	return encoding_return;
}

719
720
721

int dlsch_encoding(PHY_VARS_eNB *eNB,
		   unsigned char *a,
722
723
724
725
726
727
728
729
730
                   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)
{

731
732
733
  unsigned int G;
  unsigned int crc=1;
  unsigned short iind;
734

735
  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
736
  unsigned char harq_pid = dlsch->harq_ids[subframe];
737
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
738
  unsigned int A;
739
740
  unsigned char mod_order;
  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
741
  //  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
Xiwen JIANG's avatar
Xiwen JIANG committed
742
  uint8_t beamforming_mode=0;
743

gauthier's avatar
gauthier committed
744
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
745

746
747
  A = dlsch->harq_processes[harq_pid]->TBS; //6228
  // printf("Encoder: A: %d\n",A);
748
  mod_order = dlsch->harq_processes[harq_pid]->Qm;
749

750
  if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
Xiwen JIANG's avatar
Xiwen JIANG committed
751
    beamforming_mode = 7;
752
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
Xiwen JIANG's avatar
Xiwen JIANG committed
753
    beamforming_mode = 8;
754
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
Xiwen JIANG's avatar
Xiwen JIANG committed
755
756
    beamforming_mode = 9;
  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);
757

758

759
760
  //  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
761
#ifdef DEBUG_DLSCH_CODING
knopp's avatar
knopp committed
762
    printf("encoding thinks this is a new packet for harq_pid %d (%p) \n",harq_pid,dlsch->harq_processes[harq_pid]->b);
763
#endif
764
765
766
767
768
769
770
771
    /*
    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
knopp's avatar
knopp committed
772

773
    crc = crc24a(a,
774
                 A)>>8;
gauthier's avatar
gauthier committed
775
776
777
    a[A>>3] = ((uint8_t*)&crc)[2];
    a[1+(A>>3)] = ((uint8_t*)&crc)[1];
    a[2+(A>>3)] = ((uint8_t*)&crc)[0];
778
779
780
781
782
    //    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);
783

784
    if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
785
786
787
788
789
790
791
792
                         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)
793
      return(-1);
794
795

    for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
796

797
      if (r<dlsch->harq_processes[harq_pid]->Cminus)
798
        Kr = dlsch->harq_processes[harq_pid]->Kminus;
799
      else
800
801
        Kr = dlsch->harq_processes[harq_pid]->Kplus;

802
      Kr_bytes = Kr>>3;
803

804
805
      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      if (Kr_bytes<=64)
806
        iind = (Kr_bytes-5);
807
      else if (Kr_bytes <=128)
808
        iind = 59 + ((Kr_bytes-64)>>1);
809
      else if (Kr_bytes <= 256)
810
        iind = 91 + ((Kr_bytes-128)>>2);
811
      else if (Kr_bytes <= 768)
812
        iind = 123 + ((Kr_bytes-256)>>3);
813
      else {
814
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
815
        return(-1);
816
      }
817
818


819
820
821
#ifdef DEBUG_DLSCH_CODING
      printf("Generating Code Segment %d (%d bits)\n",r,Kr);
      // generate codewords
822

823
824
825
826
      printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A);
      printf("N_RB = %d\n",nb_rb);
      printf("Ncp %d\n",frame_parms->Ncp);
      printf("mod_order %d\n",mod_order);
827
#endif
828
829
830


#ifdef DEBUG_DLSCH_CODING
831
      printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
832
833
#endif
      start_meas(te_stats);
834
835
836
837
838
839
840
      encoder(dlsch->harq_processes[harq_pid]->c[r],
              Kr>>3,
              &dlsch->harq_processes[harq_pid]->d[r][96],
              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
              f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
              f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
             );
841
842
      stop_meas(te_stats);
#ifdef DEBUG_DLSCH_CODING
843

844
      if (r==0)
845
846
        write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);

847
848
#endif
      start_meas(i_stats);
849
850
851
852
      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]);
853
854
      stop_meas(i_stats);
    }
855

856
857
858
859
860
  }

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

861
  for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
862
#ifdef DEBUG_DLSCH_CODING
863
    printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
864
865
866
867
        r,
        G,
        Kr*3,
        mod_order,nb_rb);
868
869
870
#endif

    start_meas(rm_stats);
871
872
873
#ifdef DEBUG_DLSCH_CODING
  printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
874
    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
875
876
877
878
                                        G,  //G
                                        dlsch->harq_processes[harq_pid]->w[r],
                                        dlsch->harq_processes[harq_pid]->e+r_offset,
                                        dlsch->harq_processes[harq_pid]->C, // C
879
                                        dlsch->Nsoft,                    // Nsoft,
880
881
882
                                        dlsch->Mdlharq,
                                        dlsch->Kmimo,
                                        dlsch->harq_processes[harq_pid]->rvidx,
883
                                        dlsch->harq_processes[harq_pid]->Qm,
884
885
                                        dlsch->harq_processes[harq_pid]->Nl,
                                        r,
886
887
                                        nb_rb);
					//                                        m);                       // r
888
889
    stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING
890

891
    if (r==dlsch->harq_processes[harq_pid]->C-1)
892
      write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
893

894
895
#endif
  }
896

gauthier's avatar
gauthier committed
897
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
898

899
900
901
  return(0);
}

902
903

int dlsch_encoding_SIC(PHY_VARS_UE *ue,
904
905
906
907
908
909
910
911
		       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)
912
{
913
  
914
915
916
917
918
  unsigned int G;
  unsigned int crc=1;
  unsigned short iind;

  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
919
  unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti;
920
921
922
923
  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;
924
  //  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
925
926
927
928
929
930
  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);
931
  mod_order = dlsch->harq_processes[harq_pid]->Qm;
932
933
934
935
936
937
938
939
940
941
942
943

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


  //  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
944
945
946
#ifdef DEBUG_DLSCH_CODING
  printf("SIC encoding thinks this is a new packet \n");
#endif
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
    /*
    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;
    a[A>>3] = ((uint8_t*)&crc)[2];
    a[1+(A>>3)] = ((uint8_t*)&crc)[1];
    a[2+(A>>3)] = ((uint8_t*)&crc)[0];
    //    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;

      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      if (Kr_bytes<=64)
        iind = (Kr_bytes-5);
      else if (Kr_bytes <=128)
        iind = 59 + ((Kr_bytes-64)>>1);
      else if (Kr_bytes <= 256)
        iind = 91 + ((Kr_bytes-128)>>2);
      else if (Kr_bytes <= 768)
        iind = 123 + ((Kr_bytes-256)>>3);
      else {
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
        return(-1);
      }


#ifdef DEBUG_DLSCH_CODING
      printf("Generating Code Segment %d (%d bits)\n",r,Kr);
      // generate codewords

      printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A);
      printf("N_RB = %d\n",nb_rb);
      printf("Ncp %d\n",frame_parms->Ncp);
      printf("mod_order %d\n",mod_order);
#endif


#ifdef DEBUG_DLSCH_CODING
      printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
#endif
      start_meas(te_stats);
1016
1017
1018
1019
1020
1021
1022
      encoder(dlsch->harq_processes[harq_pid]->c[r],
              Kr>>3,
              &dlsch->harq_processes[harq_pid]->d[r][96],
              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
              f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
              f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
             );
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
      stop_meas(te_stats);
#ifdef DEBUG_DLSCH_CODING

      if (r==0)
        write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);

#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
    printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
        r,
        G,
        Kr*3,
        mod_order,nb_rb);
#endif

    start_meas(rm_stats);
1053
1054
1055
#ifdef DEBUG_DLSCH_CODING
    printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
1056
1057
1058
1059
1060
1061
1062
1063
1064
    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                        G,  //G
                                        dlsch->harq_processes[harq_pid]->w[r],
                                        dlsch->harq_processes[harq_pid]->e+r_offset,
                                        dlsch->harq_processes[harq_pid]->C, // C
                                        dlsch->Nsoft,                    // Nsoft,
                                        dlsch->Mdlharq,
                                        dlsch->Kmimo,
                                        dlsch->harq_processes[harq_pid]->rvidx,
1065
                                        dlsch->harq_processes[harq_pid]->Qm,
1066
1067
                                        dlsch->harq_processes[harq_pid]->Nl,
                                        r,
1068
1069
                                        nb_rb);
    //                                        m);                       // r
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
    stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING

    if (r==dlsch->harq_processes[harq_pid]->C-1)
      write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);

#endif
  }

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);

  return(0);
}




1087