nr_dlsch_decoding.c 50.5 KB
Newer Older
Hongzhi Wang's avatar
Hongzhi Wang committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * 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
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * 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
 */

/*! \file PHY/NR_UE_TRANSPORT/nr_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
*/

33
#include "common/utils/LOG/vcd_signal_dumper.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
34
#include "PHY/defs_nr_UE.h"
Sakthivel Velumani's avatar
Sakthivel Velumani committed
35
#include "SCHED_NR_UE/harq_nr.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
36
37
38
39
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
40
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
41
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
42
#include "SCHED_NR_UE/defs.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
43
#include "SIMULATION/TOOLS/sim.h"
Thomas Laurent's avatar
Thomas Laurent committed
44
#include "executables/nr-uesoftmodem.h"
45
#include "PHY/CODING/nrLDPC_extern.h"
Guido Casati's avatar
Guido Casati committed
46
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
47

48
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
Hongzhi Wang's avatar
Hongzhi Wang committed
49

50
//#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
Hongzhi Wang's avatar
Hongzhi Wang committed
51
52
53
54

static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0;

Hongzhi Wang's avatar
Hongzhi Wang committed
55
56
57
notifiedFIFO_t freeBlocks_dl;
notifiedFIFO_elt_t *msgToPush_dl;
int nbDlProcessing =0;
58

59
60
61

static  tpool_t pool_dl;

Hongzhi Wang's avatar
Hongzhi Wang committed
62
//extern double cpuf;
63
64
65
void init_dlsch_tpool(uint8_t num_dlsch_threads) {
  if( num_dlsch_threads==0)
    return;
66

67
  char *params=calloc(1,(num_dlsch_threads*3)+1);
68

69
70
  for (int i=0; i<num_dlsch_threads; i++) {
    memcpy(params+(i*3),"-1,",3);
71
  }
72

73
  initNamedTpool(params, &pool_dl, false,"dlsch");
74
  free(params);
75
76
}

Hongzhi Wang's avatar
Hongzhi Wang committed
77

78
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) {
Hongzhi Wang's avatar
Hongzhi Wang committed
79
  int i,r;
80
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
81
  NR_UE_DLSCH_t *dlsch=*dlschptr;
Hongzhi Wang's avatar
Hongzhi Wang committed
82
83

  if (dlsch) {
84
85
    if (N_RB_DL != 273) {
      a_segments = a_segments*N_RB_DL;
Francesco Mani's avatar
Francesco Mani committed
86
      a_segments = a_segments/273 +1;
87
    }
88

Hongzhi Wang's avatar
Hongzhi Wang committed
89
90
91
    for (i=0; i<dlsch->Mdlharq; i++) {
      if (dlsch->harq_processes[i]) {
        if (dlsch->harq_processes[i]->b) {
Thomas Laurent's avatar
Thomas Laurent committed
92
          free16(dlsch->harq_processes[i]->b,a_segments*1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
93
94
95
          dlsch->harq_processes[i]->b = NULL;
        }

96
        for (r=0; r<a_segments; r++) {
97
          free16(dlsch->harq_processes[i]->c[r],1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
98
99
100
          dlsch->harq_processes[i]->c[r] = NULL;
        }

101
        for (r=0; r<a_segments; r++)
Hongzhi Wang's avatar
Hongzhi Wang committed
102
          if (dlsch->harq_processes[i]->d[r]) {
103
            free16(dlsch->harq_processes[i]->d[r],(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
104
105
            dlsch->harq_processes[i]->d[r] = NULL;
          }
106

107
108
        for (r=0; r<a_segments; r++)
          if (dlsch->harq_processes[i]->w[r]) {
109
            free16(dlsch->harq_processes[i]->w[r],(5*8448)*sizeof(short));
110
111
112
            dlsch->harq_processes[i]->w[r] = NULL;
          }

113
        for (r=0; r<a_segments; r++) {
114
          if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]) {
Ahmed's avatar
Ahmed committed
115
116
117
118
            nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
            dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
          }
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
119
120
121
122
123

        free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
      }
    }
124

Hongzhi Wang's avatar
Hongzhi Wang committed
125
126
127
128
129
    free16(dlsch,sizeof(NR_UE_DLSCH_t));
    dlsch = NULL;
  }
}

130
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag) {
Hongzhi Wang's avatar
Hongzhi Wang committed
131
132
  NR_UE_DLSCH_t *dlsch;
  uint8_t exit_flag = 0,i,r;
133
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
134

Francesco Mani's avatar
bugfix    
Francesco Mani committed
135
136
  if (N_RB_DL != 273) {
    a_segments = a_segments*N_RB_DL;
137
    a_segments = (a_segments/273)+1;
138
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
139

140
  uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
Hongzhi Wang's avatar
Hongzhi Wang committed
141
142
143
144
145
146
  dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));

  if (dlsch) {
    memset(dlsch,0,sizeof(NR_UE_DLSCH_t));
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
147
    dlsch->number_harq_processes_for_pdsch = Mdlharq;
Hongzhi Wang's avatar
Hongzhi Wang committed
148
    dlsch->Nsoft = Nsoft;
149
    dlsch->Mlimit = 4;
Hongzhi Wang's avatar
Hongzhi Wang committed
150
    dlsch->max_ldpc_iterations = max_ldpc_iterations;
151

Hongzhi Wang's avatar
Hongzhi Wang committed
152
153
154
155
156
    for (i=0; i<Mdlharq; i++) {
      dlsch->harq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));

      if (dlsch->harq_processes[i]) {
        memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
Sakthivel Velumani's avatar
Sakthivel Velumani committed
157
        init_downlink_harq_status(dlsch->harq_processes[i]);
Hongzhi Wang's avatar
Hongzhi Wang committed
158
        dlsch->harq_processes[i]->first_tx=1;
159
        dlsch->harq_processes[i]->b = (uint8_t *)malloc16(dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
160
161

        if (dlsch->harq_processes[i]->b)
162
          memset(dlsch->harq_processes[i]->b,0,dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
163
164
165
166
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
167
          for (r=0; r<a_segments; r++) {
Ahmed's avatar
Ahmed committed
168
            dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
169
            dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
170
171

            if (dlsch->harq_processes[i]->c[r])
Hongzhi Wang's avatar
Hongzhi Wang committed
172
              memset(dlsch->harq_processes[i]->c[r],0,1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
173
174
175
            else
              exit_flag=2;

176
            dlsch->harq_processes[i]->d[r] = (short *)malloc16((5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
177
178

            if (dlsch->harq_processes[i]->d[r])
179
              memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
180
181
            else
              exit_flag=2;
182

183
            dlsch->harq_processes[i]->w[r] = (short *)malloc16((5*8448)*sizeof(short));
184
185

            if (dlsch->harq_processes[i]->w[r])
186
              memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
187
188
            else
              exit_flag=2;
Hongzhi Wang's avatar
Hongzhi Wang committed
189
190
191
192
193
194
195
196
197
198
199
          }
        }
      } else {
        exit_flag=1;
      }
    }

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

Sakthivel Velumani's avatar
Sakthivel Velumani committed
200
  LOG_D(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
201
  free_nr_ue_dlsch(&dlsch,N_RB_DL);
Hongzhi Wang's avatar
Hongzhi Wang committed
202
203
204
  return(NULL);
}

205
206
207
208
209
void nr_dlsch_unscrambling(int16_t *llr,
                           uint32_t size,
                           uint8_t q,
                           uint32_t Nid,
                           uint32_t n_RNTI) {
Hongzhi Wang's avatar
Hongzhi Wang committed
210
211
212
213
214
215
216
217
218
219
  uint8_t reset;
  uint32_t x1, x2, s=0;
  reset = 1;
  x2 = (n_RNTI<<15) + (q<<14) + Nid;

  for (int i=0; i<size; i++) {
    if ((i&0x1f)==0) {
      s = lte_gold_generic(&x1, &x2, reset);
      reset = 0;
    }
220

Hongzhi Wang's avatar
Hongzhi Wang committed
221
    if (((s>>(i&0x1f))&1)==1)
Ahmed's avatar
Ahmed committed
222
      llr[i] = -llr[i];
Hongzhi Wang's avatar
Hongzhi Wang committed
223
224
225
  }
}

226
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
227
228
229
230
231
232
233
234
235
236
237
                           UE_nr_rxtx_proc_t *proc,
                           int eNB_id,
                           short *dlsch_llr,
                           NR_DL_FRAME_PARMS *frame_parms,
                           NR_UE_DLSCH_t *dlsch,
                           NR_DL_UE_HARQ_t *harq_process,
                           uint32_t frame,
                           uint16_t nb_symb_sch,
                           uint8_t nr_slot_rx,
                           uint8_t harq_pid,
                           uint8_t is_crnti,
238
                           uint8_t llr8_flag) {
Hongzhi Wang's avatar
Hongzhi Wang committed
239
240
241
242
243
244
245
246
#if UE_TIMING_TRACE
  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;
#endif
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
247
  int32_t no_iteration_ldpc, length_dec;
248
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bits_F,err_flag=0;
Hongzhi Wang's avatar
Hongzhi Wang committed
249
  uint8_t crc_type;
250
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
Hongzhi Wang's avatar
Hongzhi Wang committed
251
  t_nrLDPC_dec_params decParams;
252
  t_nrLDPC_dec_params *p_decParams = &decParams;
253
  t_nrLDPC_time_stats procTime = {0};
254
255
  t_nrLDPC_time_stats *p_procTime =&procTime ;

256
  if (!harq_process) {
257
    LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
258
259
    return(dlsch->max_ldpc_iterations + 1);
  }
260

261
  t_nrLDPC_procBuf **p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
262
263
  // HARQ stats
  phy_vars_ue->dl_stats[harq_process->round]++;
Hongzhi Wang's avatar
Hongzhi Wang committed
264
265
266
  int16_t z [68*384];
  int8_t l [68*384];
  //__m128i l;
267
  //int16_t inv_d [68*384];
268
  uint8_t kc;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
269
  uint8_t Ilbrm = 1;
270
271
272
  uint32_t Tbslbrm;// = 950984;
  uint16_t nb_rb;// = 30;
  double Coderate;// = 0.0;
273
  uint8_t dmrs_Type = harq_process->dmrsConfigType;
274
  AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
Francesco Mani's avatar
Francesco Mani committed
275
  uint8_t nb_re_dmrs;
276

Francesco Mani's avatar
Francesco Mani committed
277
278
  if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
279
  } else {
Francesco Mani's avatar
Francesco Mani committed
280
281
    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
282

283
  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
Hongzhi Wang's avatar
Hongzhi Wang committed
284
  uint32_t i,j;
285
286
287
  __m128i *pv = (__m128i *)&z;
  __m128i *pl = (__m128i *)&l;
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
288

289
290
  //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];

Ahmed's avatar
Ahmed committed
291
  if (!dlsch_llr) {
292
    LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
293
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
294
295
296
  }

  if (!frame_parms) {
297
    LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
298
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
299
300
  }

301
302
  /*if (nr_slot_rx> (frame_parms->slots_per_frame-1)) {
    printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
303
    return(dlsch->max_ldpc_iterations + 1);
304
305
  }*/
  /*if (harq_process->harq_ack.ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
306
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
307
        phy_vars_ue->Mod_id, nr_slot_rx, harq_process->harq_ack.ack);
308
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
309
310
311
312
  //  nb_rb = dlsch->nb_rb;
  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
313
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
314
    }*/
315
  /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
Hongzhi Wang's avatar
Hongzhi Wang committed
316
317
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
318
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
319
320
  }
  */
321
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
322
  harq_process->trials[harq_process->round]++;
323
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
324
  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
Hongzhi Wang's avatar
Hongzhi Wang committed
325
  A = harq_process->TBS;
326
  ret = dlsch->max_ldpc_iterations + 1;
327
  dlsch->last_iteration_cnt = ret;
knopp's avatar
knopp committed
328
  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
Hongzhi Wang's avatar
Hongzhi Wang committed
329
  G = harq_process->G;
330
  LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
Hongzhi Wang's avatar
Hongzhi Wang committed
331

Francesco Mani's avatar
Francesco Mani committed
332
  if ((harq_process->R)<1024)
333
334
335
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
336

337
  if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
Ahmed's avatar
Ahmed committed
338
    p_decParams->BG = 2;
339
    kc = 52;
340
341

    if (Coderate < 0.3333) {
Ahmed's avatar
Ahmed committed
342
      p_decParams->R = 15;
343
    } else if (Coderate <0.6667) {
Ahmed's avatar
Ahmed committed
344
      p_decParams->R = 13;
345
    } else {
Ahmed's avatar
Ahmed committed
346
347
      p_decParams->R = 23;
    }
348
  } else {
Ahmed's avatar
Ahmed committed
349
    p_decParams->BG = 1;
350
    kc = 68;
351
352

    if (Coderate < 0.6667) {
Ahmed's avatar
Ahmed committed
353
      p_decParams->R = 13;
354
    } else if (Coderate <0.8889) {
Ahmed's avatar
Ahmed committed
355
      p_decParams->R = 23;
356
    } else {
Ahmed's avatar
Ahmed committed
357
358
359
360
      p_decParams->R = 89;
    }
  }

361
  if (harq_process->round == 0) {
362
363
364
365
366
    // This is a new packet, so compute quantities regarding segmentation
    if (A > NR_MAX_PDSCH_TBS)
      harq_process->B = A+24;
    else
      harq_process->B = A+16;
Hongzhi Wang's avatar
Hongzhi Wang committed
367

368
369
370
371
372
373
374
375
376
    nr_segmentation(NULL,
                    NULL,
                    harq_process->B,
                    &harq_process->C,
                    &harq_process->K,
                    &harq_process->Z, // [hna] Z is Zc
                    &harq_process->F,
                    p_decParams->BG);

377
378
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100))
      LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
379
380
  }

381
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
382
383
  p_decParams->Z = harq_process->Z;
  //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);
Ahmed's avatar
Ahmed committed
384
385
386
  //printf("coderate %f kc %d \n", Coderate, kc);
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
387
388
  err_flag = 0;
  r_offset = 0;
389
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
390

Francesco Mani's avatar
bugfix    
Francesco Mani committed
391
392
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
Francesco Mani's avatar
Francesco Mani committed
393
    a_segments = a_segments/273 +1;
394
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
395

396
397
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
Hongzhi Wang's avatar
Hongzhi Wang committed
398
399
    return((1+dlsch->max_ldpc_iterations));
  }
Ahmed's avatar
Ahmed committed
400

401
402
403
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
    LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);

Hongzhi Wang's avatar
Hongzhi Wang committed
404
  opp_enabled=1;
Ahmed's avatar
Ahmed committed
405
  Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
Hongzhi Wang's avatar
Hongzhi Wang committed
406
  Kr_bytes = Kr>>3;
407
  K_bits_F = Kr-harq_process->F;
Hongzhi Wang's avatar
Hongzhi Wang committed
408

Hongzhi Wang's avatar
Hongzhi Wang committed
409
  for (r=0; r<harq_process->C; r++) {
410
    //printf("start rx segment %d\n",r);
411
412
413
414
    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
#if UE_TIMING_TRACE
    start_meas(dlsch_deinterleaving_stats);
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
415
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
416
417
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
Ahmed's avatar
Ahmed committed
418
                           harq_process->w[r], // [hna] w is e
419
                           dlsch_llr+r_offset);
Hongzhi Wang's avatar
Hongzhi Wang committed
420
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
421
422
423
#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
424
425
426
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif
427
428
    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
          harq_pid,r, G,E,harq_process->F,
Hongzhi Wang's avatar
Hongzhi Wang committed
429
430
431
432
433
434
435
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
Hongzhi Wang's avatar
Hongzhi Wang committed
436
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
437

438
    if ((harq_process->Nl)<4)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
439
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
440
    else
Sakthivel Velumani's avatar
Sakthivel Velumani committed
441
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
442

Hongzhi Wang's avatar
Hongzhi Wang committed
443
    if (nr_rate_matching_ldpc_rx(Ilbrm,
444
445
446
447
448
449
450
451
                                 Tbslbrm,
                                 p_decParams->BG,
                                 p_decParams->Z,
                                 harq_process->d[r],
                                 harq_process->w[r],
                                 harq_process->C,
                                 harq_process->rvidx,
                                 (harq_process->round==0)?1:0,
452
                                 E,
453
454
                                 harq_process->F,
                                 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
455
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
456
457
458
459
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
460
      return(dlsch->max_ldpc_iterations + 1);
Ahmed's avatar
Ahmed committed
461
    } else {
Hongzhi Wang's avatar
Hongzhi Wang committed
462
463
464
465
466
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

467
    r_offset += E;
468

469
470
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
      LOG_I(PHY,"decoder input(segment %u) :",r);
Hongzhi Wang's avatar
Hongzhi Wang committed
471

472
473
      for (int i=0; i<E; i++)
        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
Hongzhi Wang's avatar
Hongzhi Wang committed
474

475
476
      LOG_D(PHY,"\n");
    }
477

478
    memset(harq_process->c[r],0,Kr_bytes);
479

480
    if (harq_process->C == 1) {
481
      if (A > NR_MAX_PDSCH_TBS)
482
483
484
        crc_type = CRC24_A;
      else
        crc_type = CRC16;
Hongzhi Wang's avatar
Hongzhi Wang committed
485

486
487
      length_dec = harq_process->B;
    } else {
Hongzhi Wang's avatar
Hongzhi Wang committed
488
      crc_type = CRC24_B;
489
490
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
491
492
493

    if (err_flag == 0) {
#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
494
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
495
#endif
496
497
498
499
500
501
502
503
      //set first 2*Z_c bits to zeros
      memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
      //set Filler bits
      memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
      //Move coded bits before filler bits
      memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
      //skip filler bits
      memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
504

505
      //Saturate coded bits before decoding into 8 bits values
506
      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
Ahmed's avatar
Ahmed committed
507
508
509
        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
510
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
Ahmed's avatar
Ahmed committed
511
      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
512
513
514
515
                                         (int8_t *)&pl[0],
                                         llrProcBuf,
                                         p_nrLDPC_procBuf[r],
                                         p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
516
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
517

Ahmed's avatar
Ahmed committed
518
      // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
519
      if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
520
        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
521

522
        if (r==0) {
523
          for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
524
        }
525

526
527
        //Temporary hack
        no_iteration_ldpc = dlsch->max_ldpc_iterations;
528
        ret = no_iteration_ldpc;
529
      } else {
Roberto Louro Magueta's avatar
Roberto Louro Magueta committed
530
        LOG_D(PHY,"CRC NOT OK\n\033[0m");
Ahmed's avatar
Ahmed committed
531
532
533
      }

      nb_total_decod++;
534
535

      if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
Ahmed's avatar
Ahmed committed
536
537
538
        nb_error_decod++;
      }

539
      for (int m=0; m < Kr>>3; m ++) {
Ahmed's avatar
Ahmed committed
540
541
        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
542

543
544
      if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
        for (int k=0; k<A>>3; k++)
545
          LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
Hongzhi Wang's avatar
Hongzhi Wang committed
546

547
548
        LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
549
550
551
552
553
554
555

#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }

    if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
556
      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
Hongzhi Wang's avatar
Hongzhi Wang committed
557
558
559
560
561
      err_flag = 1;
    }
  }

  if (err_flag == 1) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
562
    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",
563
          phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
564
    harq_process->ack = 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
565
566
    harq_process->errors[harq_process->round]++;

567
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
568
569
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
570
      phy_vars_ue->dl_stats[4]++;
Hongzhi Wang's avatar
Hongzhi Wang committed
571
    }
572

573
574
575
    if(is_crnti) {
      LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
            phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
576
577
    }

578
    return((1 + dlsch->max_ldpc_iterations));
Hongzhi Wang's avatar
Hongzhi Wang committed
579
  } else {
580
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
581
          phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
Hongzhi Wang's avatar
Hongzhi Wang committed
582
583
    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
584
    harq_process->ack = 1;
585

586
    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
587
    //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
Hongzhi Wang's avatar
Hongzhi Wang committed
588

589
590
    if(is_crnti) {
      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
591
592
    }

593
    //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);
Hongzhi Wang's avatar
Hongzhi Wang committed
594
595
596
597
  }

  // Reassembly of Transport block here
  offset = 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
598
599
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
600
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
601

Hongzhi Wang's avatar
Hongzhi Wang committed
602
  for (r=0; r<harq_process->C; r++) {
Hongzhi Wang's avatar
Hongzhi Wang committed
603
    memcpy(harq_process->b+offset,
604
605
           harq_process->c[r],
           Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
Hongzhi Wang's avatar
Hongzhi Wang committed
606
607
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));

608
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
609
610
      LOG_D(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
      LOG_D(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
611
            (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
612
      LOG_D(PHY,"b[0] = %p,c[%d] = %p\n",
613
614
615
616
617
618
619
620
621
            (void *)(uint64_t)(harq_process->b[offset]),
            harq_process->F>>3,
            (void *)(uint64_t)(harq_process->c[r]) );

      if (frame%100 == 0) {
        LOG_D (PHY, "Printing 60 first payload bytes at frame: %d ", frame);

        for (int i = 0; i <60 ; i++) { //Kr_bytes
          LOG_D(PHY, "[%d] : %x ", i, harq_process->b[i]);
622
623
        }
      }
624
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
625
626
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
627
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
628
629
630
631
  dlsch->last_iteration_cnt = ret;
  return(ret);
}

632

633
uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Ahmed's avatar
Ahmed committed
634
635
636
637
638
639
640
641
                                    UE_nr_rxtx_proc_t *proc,
                                    int eNB_id,
                                    short *dlsch_llr,
                                    NR_DL_FRAME_PARMS *frame_parms,
                                    NR_UE_DLSCH_t *dlsch,
                                    NR_DL_UE_HARQ_t *harq_process,
                                    uint32_t frame,
                                    uint16_t nb_symb_sch,
642
                                    uint8_t nr_slot_rx,
Ahmed's avatar
Ahmed committed
643
644
                                    uint8_t harq_pid,
                                    uint8_t is_crnti,
645
                                    uint8_t llr8_flag) {
Hongzhi Wang's avatar
Hongzhi Wang committed
646
647
648
649
650
651
652
653
#if UE_TIMING_TRACE
  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;
#endif
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
654
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bits_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
655
656
  uint8_t crc_type;
  //UE_rxtx_proc_t *proc = &phy_vars_ue->proc;
657
  int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
658
659
660
661
662
  /*uint8_t C;
  uint8_t Qm;
  uint8_t r_thread;
  uint32_t Er, Gp,GpmodC;*/
  t_nrLDPC_dec_params decParams;
663
  t_nrLDPC_dec_params *p_decParams = &decParams;
664
  t_nrLDPC_time_stats procTime;
665
  t_nrLDPC_time_stats *p_procTime =&procTime ;
666
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
667
668

  if (!harq_process) {
669
    LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
670
671
    return(dlsch->max_ldpc_iterations);
  }
672
673

  t_nrLDPC_procBuf *p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
674
  uint8_t Nl=4;
675
676
  int16_t z [68*384];
  int8_t l [68*384];
677
  uint8_t kc;
678
  uint8_t Ilbrm = 1;
679
  uint32_t Tbslbrm = 950984;
680
681
  uint16_t nb_rb = 30;
  double Coderate = 0.0;
Hongzhi Wang's avatar
Hongzhi Wang committed
682
  uint8_t dmrs_type = harq_process->dmrsConfigType;
683
  uint8_t nb_re_dmrs;
684

Hongzhi Wang's avatar
Hongzhi Wang committed
685
  if (dmrs_type == NFAPI_NR_DMRS_TYPE1)
686
687
688
689
    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
  else
    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;

690
  uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos);
691
  uint32_t i,j;
692
693
  __m128i *pv = (__m128i *)&z;
  __m128i *pl = (__m128i *)&l;
694
695
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
696
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
697
698

  if (!dlsch_llr) {
699
    LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
700
701
702
703
    return(dlsch->max_ldpc_iterations);
  }

  if (!frame_parms) {
704
    LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
705
706
707
    return(dlsch->max_ldpc_iterations);
  }

708
709
710
711
  /* if (nr_slot_rx> (frame_parms->slots_per_frame-1)) {
     printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
     return(dlsch->max_ldpc_iterations);
   }
Hongzhi Wang's avatar
Hongzhi Wang committed
712

713
714
715
716
   if (dlsch->harq_ack[nr_slot_rx].ack != 2) {
     LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
         phy_vars_ue->Mod_id, nr_slot_rx, dlsch->harq_ack[nr_slot_rx].ack);
   }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
717
718
719
720
721
  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
    return(max_ldpc_iterations);
    }*/
722
  /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
Hongzhi Wang's avatar
Hongzhi Wang committed
723
724
725
726
727
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
    return(max_ldpc_iterations);
  }
  */
728
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
729
  harq_process->trials[harq_process->round]++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
730
731
  // HARQ stats
  phy_vars_ue->dl_stats[harq_process->round]++;
732
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
733
  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
734
  A = harq_process->TBS;
Hongzhi Wang's avatar
Hongzhi Wang committed
735
736
  ret = dlsch->max_ldpc_iterations + 1;
  dlsch->last_iteration_cnt = ret;
737
  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
Hongzhi Wang's avatar
Hongzhi Wang committed
738
  G = harq_process->G;
739
740
  LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d  mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs,
        harq_process->Nl, nb_symb_sch,nb_rb);
Hongzhi Wang's avatar
Hongzhi Wang committed
741
742
743
744
  proc->decoder_main_available = 1;
  proc->decoder_thread_available = 0;
  proc->decoder_thread_available1 = 0;

Francesco Mani's avatar
Francesco Mani committed
745
  if ((harq_process->R)<1024)
746
747
748
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
749

750
  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
751
    p_decParams->BG = 2;
752
    kc = 52;
753
754

    if (Coderate < 0.3333) {
755
      p_decParams->R = 15;
756
    } else if (Coderate <0.6667) {
757
      p_decParams->R = 13;
758
    } else {
759
760
      p_decParams->R = 23;
    }
761
  } else {
762
    p_decParams->BG = 1;
763
    kc = 68;
764
765

    if (Coderate < 0.6667) {
766
      p_decParams->R = 13;
767
    } else if (Coderate <0.8889) {
768
      p_decParams->R = 23;
769
    } else {
770
771
772
      p_decParams->R = 89;
    }
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
773

774
  if (harq_process->round == 0) {
775
    // This is a new packet, so compute quantities regarding segmentation
776
    if (A > NR_MAX_PDSCH_TBS)
777
778
779
      harq_process->B = A+24;
    else
      harq_process->B = A+16;
780

781
782
783
784
785
786
787
788
789
    nr_segmentation(NULL,
                    NULL,
                    harq_process->B,
                    &harq_process->C,
                    &harq_process->K,
                    &harq_process->Z,
                    &harq_process->F,
                    p_decParams->BG);
  }
790

791
  p_decParams->Z = harq_process->Z;
792
793
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
794
795
  err_flag = 0;
  r_offset = 0;
796
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
797

Francesco Mani's avatar
bugfix    
Francesco Mani committed
798
799
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
Francesco Mani's avatar
Francesco Mani committed
800
    a_segments = a_segments/273 +1;
801
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
802

803
804
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
Hongzhi Wang's avatar
Hongzhi Wang committed
805
806
    return((1+dlsch->max_ldpc_iterations));
  }
807

808
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
Sakthivel Velumani's avatar
Sakthivel Velumani committed
809
    LOG_D(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
810

Hongzhi Wang's avatar
Hongzhi Wang committed
811
  notifiedFIFO_elt_t *res_dl;
Hongzhi Wang's avatar
Hongzhi Wang committed
812
813
  opp_enabled=1;

814
815
816
817
818
  if (harq_process->C>1) {
    for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++) {
      if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
819

820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
      AssertFatal((msgToPush_dl=pullNotifiedFIFO_nothreadSafe(&freeBlocks_dl)) != NULL,"chained list failure");
      nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush_dl);
      curMsg->UE=phy_vars_ue;
      nbDlProcessing++;
      memset(&curMsg->proc, 0, sizeof(curMsg->proc));
      curMsg->proc.frame_rx   = proc->frame_rx;
      curMsg->proc.nr_slot_rx = proc->nr_slot_rx;
      curMsg->proc.thread_id  = proc->thread_id;
      curMsg->proc.num_seg    = nb_seg;
      curMsg->proc.eNB_id= eNB_id;
      curMsg->proc.harq_pid=harq_pid;
      curMsg->proc.llr8_flag = llr8_flag;
      msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg;
      pushTpool(&pool_dl, msgToPush_dl);
      /*Qm= harq_process->Qm;