nr_dlsch_decoding.c 51.4 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"
laurent's avatar
laurent committed
44
#include "executables/nr-uesoftmodem.h"
45
#include "PHY/CODING/nrLDPC_extern.h"
cig's avatar
cig 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
void init_dlsch_tpool(uint8_t num_dlsch_threads)
64
{
65
    if( num_dlsch_threads==0)
66 67
    	return;

68 69 70
  char *params=calloc(1,(num_dlsch_threads*3)+1);
  for (int i=0; i<num_dlsch_threads; i++) {
    memcpy(params+(i*3),"-1,",3);
71
  }
72
  initNamedTpool(params, &pool_dl, false,"dlsch");
73
  free(params);
74 75
}

Hongzhi Wang's avatar
Hongzhi Wang committed
76

77
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
Hongzhi Wang's avatar
Hongzhi Wang committed
78 79 80
{

  int i,r;
81
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
82
  NR_UE_DLSCH_t *dlsch=*dlschptr;
Hongzhi Wang's avatar
Hongzhi Wang committed
83 84

  if (dlsch) {
85 86
    if (N_RB_DL != 273) {
      a_segments = a_segments*N_RB_DL;
87
      a_segments = a_segments/273 +1;
88 89 90
    }  
 

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

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

103
        for (r=0; r<a_segments; r++)
Hongzhi Wang's avatar
Hongzhi Wang committed
104
          if (dlsch->harq_processes[i]->d[r]) {
105
            free16(dlsch->harq_processes[i]->d[r],(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
106 107
            dlsch->harq_processes[i]->d[r] = NULL;
          }
108
        
109 110
        for (r=0; r<a_segments; r++)
          if (dlsch->harq_processes[i]->w[r]) {
111
            free16(dlsch->harq_processes[i]->w[r],(5*8448)*sizeof(short));
112 113 114
            dlsch->harq_processes[i]->w[r] = NULL;
          }

115
        for (r=0; r<a_segments; r++) {
Ahmed's avatar
Ahmed committed
116 117 118 119 120
          if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
            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
121 122 123 124 125

        free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
      }
    }
126
      
Hongzhi Wang's avatar
Hongzhi Wang committed
127 128 129 130 131
    free16(dlsch,sizeof(NR_UE_DLSCH_t));
    dlsch = NULL;
  }
}

132
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
133 134 135 136 137
{

  NR_UE_DLSCH_t *dlsch;
  uint8_t exit_flag = 0,i,r;

138
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
139

Francesco Mani's avatar
Francesco Mani committed
140 141
  if (N_RB_DL != 273) {
    a_segments = a_segments*N_RB_DL;
142
    a_segments = (a_segments/273)+1;
143
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
144

145
  uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
Hongzhi Wang's avatar
Hongzhi Wang committed
146 147 148 149 150 151 152

  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
153
    dlsch->number_harq_processes_for_pdsch = Mdlharq;
Hongzhi Wang's avatar
Hongzhi Wang committed
154
    dlsch->Nsoft = Nsoft;
155
    dlsch->Mlimit = 4;
Hongzhi Wang's avatar
Hongzhi Wang committed
156
    dlsch->max_ldpc_iterations = max_ldpc_iterations;
157
 
Hongzhi Wang's avatar
Hongzhi Wang committed
158 159 160 161 162
    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
163
        init_downlink_harq_status(dlsch->harq_processes[i]);
Hongzhi Wang's avatar
Hongzhi Wang committed
164
        dlsch->harq_processes[i]->first_tx=1;
165
        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
166 167

        if (dlsch->harq_processes[i]->b)
168
          memset(dlsch->harq_processes[i]->b,0,dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
169 170 171 172
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
173
          for (r=0; r<a_segments; r++) { 
Ahmed's avatar
Ahmed committed
174
            dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
Hongzhi Wang's avatar
Hongzhi Wang committed
175
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
176 177

            if (dlsch->harq_processes[i]->c[r])
Hongzhi Wang's avatar
Hongzhi Wang committed
178
              memset(dlsch->harq_processes[i]->c[r],0,1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
179 180 181
            else
              exit_flag=2;

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

            if (dlsch->harq_processes[i]->d[r])
185
              memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
186 187
            else
              exit_flag=2;
188

189
            dlsch->harq_processes[i]->w[r] = (short*)malloc16((5*8448)*sizeof(short));
190 191

            if (dlsch->harq_processes[i]->w[r])
192
              memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
193 194
            else
              exit_flag=2;
Hongzhi Wang's avatar
Hongzhi Wang committed
195 196 197 198 199 200 201 202 203 204 205
          }
        }
      } else {
        exit_flag=1;
      }
    }

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

Sakthivel Velumani's avatar
Sakthivel Velumani committed
206
  LOG_D(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
207
  free_nr_ue_dlsch(&dlsch,N_RB_DL);
Hongzhi Wang's avatar
Hongzhi Wang committed
208 209 210 211

  return(NULL);
}

Hongzhi Wang's avatar
Hongzhi Wang committed
212
void nr_dlsch_unscrambling(int16_t* llr,
hongzhi wang's avatar
hongzhi wang committed
213
                         uint32_t size,
Hongzhi Wang's avatar
Hongzhi Wang committed
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
                         uint8_t q,
                         uint32_t Nid,
                         uint32_t n_RNTI) {

  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;
    }
    if (((s>>(i&0x1f))&1)==1)
Ahmed's avatar
Ahmed committed
230
      llr[i] = -llr[i];
Hongzhi Wang's avatar
Hongzhi Wang committed
231 232 233 234
  }

}

235
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
236 237 238 239 240 241 242 243 244 245 246 247
                           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,
                           uint8_t llr8_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
248 249 250 251 252 253 254 255 256 257
{

#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;
258
  int32_t no_iteration_ldpc, length_dec;
259
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bits_F,err_flag=0;
Hongzhi Wang's avatar
Hongzhi Wang committed
260
  uint8_t crc_type;
261
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
Hongzhi Wang's avatar
Hongzhi Wang committed
262 263 264 265
  t_nrLDPC_dec_params decParams;
  t_nrLDPC_dec_params* p_decParams = &decParams;
  t_nrLDPC_time_stats procTime;
  t_nrLDPC_time_stats* p_procTime =&procTime ;
266 267
  
  if (!harq_process) {
268
    LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
269 270
    return(dlsch->max_ldpc_iterations + 1);
  }
271
  t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
272

273 274
  // HARQ stats
  phy_vars_ue->dl_stats[harq_process->round]++;
275
    
Hongzhi Wang's avatar
Hongzhi Wang committed
276 277 278
  int16_t z [68*384];
  int8_t l [68*384];
  //__m128i l;
279
  //int16_t inv_d [68*384];
280
  uint8_t kc;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
281
  uint8_t Ilbrm = 1;
282 283 284 285

  uint32_t Tbslbrm;// = 950984;
  uint16_t nb_rb;// = 30;
  double Coderate;// = 0.0;
286

287
  uint8_t dmrs_Type = harq_process->dmrsConfigType;
288
  AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
289 290 291 292 293 294 295
  uint8_t nb_re_dmrs;
  if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
  }
  else {
    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
  }
296
  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
Hongzhi Wang's avatar
Hongzhi Wang committed
297 298 299 300 301

  uint32_t i,j;

  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
Hongzhi Wang's avatar
Hongzhi Wang committed
302 303
  
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
304
  
305 306
  //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];

Ahmed's avatar
Ahmed committed
307
  if (!dlsch_llr) {
308
    LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
309
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
310 311 312
  }

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

317 318
  /*if (nr_slot_rx> (frame_parms->slots_per_frame-1)) {
    printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
319
    return(dlsch->max_ldpc_iterations + 1);
320
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
321

322
  /*if (harq_process->harq_ack.ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
323
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
324
        phy_vars_ue->Mod_id, nr_slot_rx, harq_process->harq_ack.ack);
325
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
326 327 328 329 330 331

  //  nb_rb = dlsch->nb_rb;

  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
332
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
333 334
    }*/

335
  /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
Hongzhi Wang's avatar
Hongzhi Wang committed
336 337
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
338
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
339 340 341
  }
  */

342 343
  nb_rb = harq_process->nb_rb;

Hongzhi Wang's avatar
Hongzhi Wang committed
344 345
  harq_process->trials[harq_process->round]++;

346 347
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs

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

Hongzhi Wang's avatar
Hongzhi Wang committed
350
  A = harq_process->TBS;
351
  ret = dlsch->max_ldpc_iterations + 1;
352
  dlsch->last_iteration_cnt = ret;
353
 
Raymond Knopp's avatar
Raymond Knopp committed
354
  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
355 356
  G = harq_process->G;

357
  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
358

Francesco Mani's avatar
Francesco Mani committed
359
  if ((harq_process->R)<1024)
360 361 362
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
363

364
  if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25)
Ahmed's avatar
Ahmed committed
365 366
  {
    p_decParams->BG = 2;
367
    kc = 52;
Ahmed's avatar
Ahmed committed
368 369 370 371 372 373 374 375 376 377 378 379
    if (Coderate < 0.3333){
      p_decParams->R = 15;
    }
    else if (Coderate <0.6667){
      p_decParams->R = 13;
    }
    else {
      p_decParams->R = 23;
    }
  }
  else{
    p_decParams->BG = 1;
380
    kc = 68;
Ahmed's avatar
Ahmed committed
381 382 383 384 385 386 387 388 389 390 391
    if (Coderate < 0.6667){
      p_decParams->R = 13;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
    }
    else {
      p_decParams->R = 89;
    }
  }

392 393

  if (harq_process->round == 0) {
394 395
  // This is a new packet, so compute quantities regarding segmentation
  if (A > NR_MAX_PDSCH_TBS)
396 397 398 399
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;

400 401 402 403 404 405 406 407 408
    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);

409 410
  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);
411
  }
412
  
Hongzhi Wang's avatar
Hongzhi Wang committed
413
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
414 415 416 417

  p_decParams->Z = harq_process->Z;
  //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);

Ahmed's avatar
Ahmed committed
418 419 420 421
  //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
422 423 424 425

  err_flag = 0;
  r_offset = 0;

426
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
427

Francesco Mani's avatar
Francesco Mani committed
428 429
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
430
    a_segments = a_segments/273 +1;
431
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
432

433 434
  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
435 436
    return((1+dlsch->max_ldpc_iterations));
  }
Ahmed's avatar
Ahmed committed
437

438 439 440
  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
441 442 443

  opp_enabled=1;

Ahmed's avatar
Ahmed committed
444
  Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
Hongzhi Wang's avatar
Hongzhi Wang committed
445
  Kr_bytes = Kr>>3;
446
  K_bits_F = Kr-harq_process->F;
Hongzhi Wang's avatar
Hongzhi Wang committed
447

Hongzhi Wang's avatar
Hongzhi Wang committed
448 449
  for (r=0; r<harq_process->C; r++) {

450
    //printf("start rx segment %d\n",r);
451 452 453 454 455
    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
456

Hongzhi Wang's avatar
Hongzhi Wang committed
457
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
458

459

460 461
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
Ahmed's avatar
Ahmed committed
462
                           harq_process->w[r], // [hna] w is e
463 464
                           dlsch_llr+r_offset);

Hongzhi Wang's avatar
Hongzhi Wang committed
465
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
466

467 468 469 470

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif
471

Hongzhi Wang's avatar
Hongzhi Wang committed
472 473 474 475
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

476 477
    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
478 479 480 481 482 483 484
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
485

Hongzhi Wang's avatar
Hongzhi Wang committed
486

Hongzhi Wang's avatar
Hongzhi Wang committed
487
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
488

489
    if ((harq_process->Nl)<4)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
490
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
491
    else
Sakthivel Velumani's avatar
Sakthivel Velumani committed
492
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
493

494

Hongzhi Wang's avatar
Hongzhi Wang committed
495
    if (nr_rate_matching_ldpc_rx(Ilbrm,
496 497 498 499 500 501 502 503
                                 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,
504
                                 E,
cig's avatar
cig committed
505 506
                                 harq_process->F,
                                 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
507
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
508 509 510 511
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
512
      return(dlsch->max_ldpc_iterations + 1);
Ahmed's avatar
Ahmed committed
513
    } else {
514

Hongzhi Wang's avatar
Hongzhi Wang committed
515 516 517 518 519
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

520
    r_offset += E;
521

522 523 524
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
  {
    LOG_I(PHY,"decoder input(segment %u) :",r);
525
    for (int i=0;i<E;i++)
526 527 528
     LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
    LOG_D(PHY,"\n");
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
529 530 531

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

532

533
    if (harq_process->C == 1){
534
      if (A > NR_MAX_PDSCH_TBS)
535 536 537 538 539 540
    		crc_type = CRC24_A;
    	else
    		crc_type = CRC16;
    	
	length_dec = harq_process->B;

541 542
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
543
      crc_type = CRC24_B;
544 545
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
546 547 548 549

    if (err_flag == 0) {

#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
550
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
551 552 553
#endif


554 555 556 557 558 559 560 561 562 563
      //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));
      //Saturate coded bits before decoding into 8 bits values
      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
Ahmed's avatar
Ahmed committed
564 565 566 567
      {
        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
      }

cig's avatar
cig committed
568

Hongzhi Wang's avatar
Hongzhi Wang committed
569
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
570

Ahmed's avatar
Ahmed committed
571 572 573
      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                           (int8_t*)&pl[0],
                           llrProcBuf,
574
                           p_nrLDPC_procBuf[r],
575
                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
576
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
577

Ahmed's avatar
Ahmed committed
578 579
      // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
580
        LOG_I(PHY,"Segment %u CRC OK\n\033[0m",r);
581
        if (r==0) {
rmagueta's avatar
rmagueta committed
582
          for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);
583
        }
584

585 586
        //Temporary hack
        no_iteration_ldpc = dlsch->max_ldpc_iterations;
587
        ret = no_iteration_ldpc;
Ahmed's avatar
Ahmed committed
588 589
      }
      else {
590
        LOG_I(PHY,"CRC NOT OK\n\033[0m");
591
        ret = 1 + dlsch->max_ldpc_iterations;
Ahmed's avatar
Ahmed committed
592 593
      }

594

Ahmed's avatar
Ahmed committed
595 596 597 598 599 600 601 602 603
      nb_total_decod++;
      if (no_iteration_ldpc > dlsch->max_ldpc_iterations){
        nb_error_decod++;
      }

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

605 606 607 608 609 610
      if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
      	{
        for (int k=0;k<A>>3;k++)
          LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
        LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
611 612 613 614 615 616


#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }
617
    
Hongzhi Wang's avatar
Hongzhi Wang committed
618 619

    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
620
      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
621 622 623 624 625
      err_flag = 1;
    }
  }

  if (err_flag == 1) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
626
    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",
627
        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);
628

Hongzhi Wang's avatar
Hongzhi Wang committed
629 630 631 632 633
    harq_process->harq_ack.ack = 0;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
    harq_process->errors[harq_process->round]++;

634
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
635 636
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
637
      phy_vars_ue->dl_stats[4]++;
Hongzhi Wang's avatar
Hongzhi Wang committed
638
    }
639

Hongzhi Wang's avatar
Hongzhi Wang committed
640 641
    if(is_crnti)
    {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
642
    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",
643
               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
644 645
    }

646
    return((1 + dlsch->max_ldpc_iterations));
Hongzhi Wang's avatar
Hongzhi Wang committed
647
  } else {
648

649 650
    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",
	  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
651 652 653 654 655 656

    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
    harq_process->harq_ack.ack = 1;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
657
    
658
    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
659 660 661 662
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);

    if(is_crnti)
    {
663
    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
664 665 666 667 668 669 670
    }
    //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);

  }

  // Reassembly of Transport block here
  offset = 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
671 672
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
673

674

Hongzhi Wang's avatar
Hongzhi Wang committed
675
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
676

Hongzhi Wang's avatar
Hongzhi Wang committed
677 678
  for (r=0; r<harq_process->C; r++) {

Hongzhi Wang's avatar
Hongzhi Wang committed
679
    memcpy(harq_process->b+offset,
680 681
	   harq_process->c[r],
	   Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
Hongzhi Wang's avatar
Hongzhi Wang committed
682 683
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));

684 685 686 687 688 689 690
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
      {
      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",
             (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
      LOG_D(PHY,"b[0] = %p,c[%d] = %p\n",
              (void *)(uint64_t)(harq_process->b[offset]),
Hongzhi Wang's avatar
Hongzhi Wang committed
691
              harq_process->F>>3,
692 693 694 695 696
              (void *)(uint64_t)(harq_process->c[r]) );
      if (frame%100 == 0){
          LOG_D (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
          for (int i = 0; i <10 ; i++){ //Kr_bytes
            LOG_D(PHY, "[%d] : %x ", i, harq_process->b[i]);
697
          }
698 699
        }
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
700 701
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
702
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
703

Hongzhi Wang's avatar
Hongzhi Wang committed
704 705 706 707 708
  dlsch->last_iteration_cnt = ret;

  return(ret);
}

709

710
uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Ahmed's avatar
Ahmed committed
711 712 713 714 715 716 717 718
                                    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,
719
                                    uint8_t nr_slot_rx,
Ahmed's avatar
Ahmed committed
720 721 722
                                    uint8_t harq_pid,
                                    uint8_t is_crnti,
                                    uint8_t llr8_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
723 724 725 726 727 728 729 730 731 732
{

#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;
733
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bits_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
734 735
  uint8_t crc_type;
  //UE_rxtx_proc_t *proc = &phy_vars_ue->proc;
736
  int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
737 738 739 740 741
  /*uint8_t C;
  uint8_t Qm;
  uint8_t r_thread;
  uint32_t Er, Gp,GpmodC;*/
  t_nrLDPC_dec_params decParams;
742 743 744
  t_nrLDPC_dec_params* p_decParams = &decParams;
  t_nrLDPC_time_stats procTime;
  t_nrLDPC_time_stats* p_procTime =&procTime ;
745
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
746
    if (!harq_process) {
747
    LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
748 749
    return(dlsch->max_ldpc_iterations);
  }
750
  t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
751
  uint8_t Nl=4;
752 753
  int16_t z [68*384];
  int8_t l [68*384];
754
  uint8_t kc;
755
  uint8_t Ilbrm = 1;
756
  uint32_t Tbslbrm = 950984;
757 758
  uint16_t nb_rb = 30;
  double Coderate = 0.0;
Hongzhi Wang's avatar
Hongzhi Wang committed
759
  uint8_t dmrs_type = harq_process->dmrsConfigType;
cig's avatar
cig committed
760

761
  uint8_t nb_re_dmrs;
Hongzhi Wang's avatar
Hongzhi Wang committed
762
  if (dmrs_type == NFAPI_NR_DMRS_TYPE1)
763 764 765 766
    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
  else
    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;

767
  uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos); 
Hongzhi Wang's avatar
Hongzhi Wang committed
768
  
769
  uint32_t i,j;
Hongzhi Wang's avatar
Hongzhi Wang committed
770

771 772 773 774
  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
775

Hongzhi Wang's avatar
Hongzhi Wang committed
776
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
777 778

  if (!dlsch_llr) {
779
    LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
780 781 782
    return(dlsch->max_ldpc_iterations);
  }

783

Hongzhi Wang's avatar
Hongzhi Wang committed
784 785

  if (!frame_parms) {
786
    LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
787 788 789
    return(dlsch->max_ldpc_iterations);
  }

790 791
 /* if (nr_slot_rx> (frame_parms->slots_per_frame-1)) {
    printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
Hongzhi Wang's avatar
Hongzhi Wang committed
792 793 794
    return(dlsch->max_ldpc_iterations);
  }

795
  if (dlsch->harq_ack[nr_slot_rx].ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
796
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
797
        phy_vars_ue->Mod_id, nr_slot_rx, dlsch->harq_ack[nr_slot_rx].ack);
798
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
799 800 801 802 803 804 805

  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
    return(max_ldpc_iterations);
    }*/

806
  /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
Hongzhi Wang's avatar
Hongzhi Wang committed
807 808 809 810 811 812
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
    return(max_ldpc_iterations);
  }
  */

813
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
814 815
  harq_process->trials[harq_process->round]++;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
816 817 818
  // HARQ stats
  phy_vars_ue->dl_stats[harq_process->round]++;

819 820
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs

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

823
  A = harq_process->TBS;
Hongzhi Wang's avatar
Hongzhi Wang committed
824

Hongzhi Wang's avatar
Hongzhi Wang committed
825 826
  ret = dlsch->max_ldpc_iterations + 1;
  dlsch->last_iteration_cnt = ret;
Hongzhi Wang's avatar
Hongzhi Wang committed
827

828
  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
829 830 831

  G = harq_process->G;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
832
  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);
833

Hongzhi Wang's avatar
Hongzhi Wang committed
834 835 836 837 838
  proc->decoder_main_available = 1;
  proc->decoder_thread_available = 0;
  proc->decoder_thread_available1 = 0;


Francesco Mani's avatar
Francesco Mani committed
839
  if ((harq_process->R)<1024)
840 841 842
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
843

844
  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25)
845 846
  {
    p_decParams->BG = 2;
847
    kc = 52;
848 849 850 851 852 853 854 855 856 857 858 859
    if (Coderate < 0.3333){
      p_decParams->R = 15;
    }
    else if (Coderate <0.6667){
      p_decParams->R = 13;
    }
    else {
      p_decParams->R = 23;
    }
  }
  else{
    p_decParams->BG = 1;
860
    kc = 68;
861 862 863 864 865 866 867 868 869 870
    if (Coderate < 0.6667){
      p_decParams->R = 13;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
    }
    else {
      p_decParams->R = 89;
    }
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
871

872 873
  if (harq_process->round == 0) {
      // This is a new packet, so compute quantities regarding segmentation
874
    if (A > NR_MAX_PDSCH_TBS)
875 876 877 878
	  	  harq_process->B = A+24;
	  else
	  	  harq_process->B = A+16;

879 880 881 882 883 884 885 886 887 888 889
      nr_segmentation(NULL,
                      NULL,
                      harq_process->B,
                      &harq_process->C,
                      &harq_process->K,
                      &harq_process->Z,
                      &harq_process->F,
                      p_decParams->BG);


    }
Hongzhi Wang's avatar
Hongzhi Wang committed
890 891
    
    p_decParams->Z = harq_process->Z;
892

893 894
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
895 896 897 898

  err_flag = 0;
  r_offset = 0;

899
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
900

Francesco Mani's avatar
Francesco Mani committed
901 902
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
903
    a_segments = a_segments/273 +1;
904
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
905

906 907
  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
908 909
    return((1+dlsch->max_ldpc_iterations));
  }
910
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
Sakthivel Velumani's avatar
Sakthivel Velumani committed
911
    LOG_D(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
912

Hongzhi Wang's avatar
Hongzhi Wang committed
913

Hongzhi Wang's avatar
Hongzhi Wang committed
914
  notifiedFIFO_elt_t *res_dl;
Hongzhi Wang's avatar
Hongzhi Wang committed
915
  opp_enabled=1;
916 917
  if (harq_process->C>1) {
	for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
918
	  if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
Hongzhi Wang's avatar
Hongzhi Wang committed
919
	          pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
920 921
	        }

Hongzhi Wang's avatar
Hongzhi Wang committed
922 923
	  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);
924
	  curMsg->UE=phy_vars_ue;
Hongzhi Wang's avatar
Hongzhi Wang committed
925 926 927
	  
	  nbDlProcessing++;

928 929

	  memset(&curMsg->proc, 0, sizeof(curMsg->proc));
930 931 932 933
	  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;
934 935 936 937 938

	  curMsg->proc.eNB_id= eNB_id;
	  curMsg->proc.harq_pid=harq_pid;
	  curMsg->proc.llr8_flag = llr8_flag;

939
	  msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg;
940
	  pushTpool(&pool_dl, msgToPush_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
941

Ahmed's avatar
Ahmed committed
942 943 944 945
  /*Qm= harq_process->Qm;
    Nl=harq_process->Nl;
    r_thread = harq_process->C/2-1;
    C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
946

Ahmed's avatar
Ahmed committed
947 948
    Gp = G/Nl/Qm;
    GpmodC = Gp%C;
Hongzhi Wang's avatar
Hongzhi Wang committed
949 950


Ahmed's avatar
Ahmed committed
951 952 953 954 955
    if (r_thread < (C-(GpmodC)))
      Er = Nl*Qm * (Gp/C);
    else
      Er = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
    printf("mthread Er %d\n", Er);
Hongzhi Wang's avatar
Hongzhi Wang committed
956

Ahmed's avatar
Ahmed committed
957
    printf("mthread instance_cnt_dlsch_td %d\n",  proc->instance_cnt_dlsch_td);*/
958
	  }
Ahmed's avatar
Ahmed committed
959 960 961 962 963
  //proc->decoder_main_available = 1;
  }

    r = 0;  
    if (r==0) r_offset =0;
Hongzhi Wang's avatar
Hongzhi Wang committed
964

965
    Kr = harq_process->K;
Hongzhi Wang's avatar
Hongzhi Wang committed
966
    Kr_bytes = Kr>>3;
967
    K_bits_F = Kr-harq_process->F;
Hongzhi Wang's avatar
Hongzhi Wang committed
968

969 970 971 972 973 974 975 976 977 978 979 980 981 982 983
    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);

    /*
    printf("Subblock deinterleaving, dlsch_llr %p, w %p\n",
     dlsch_llr+r_offset,
     &harq_process->w[r]);
    */
#if UE_TIMING_TRACE
    start_meas(dlsch_deinterleaving_stats);
#endif
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
                           harq_process->w[r],
                           dlsch_llr+r_offset);

984
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
985
        for (int i =0; i<16; i++)
986
              LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
987 988 989 990 991

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
992 993 994 995
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

996 997
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
    LOG_I(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",
Hongzhi Wang's avatar
Hongzhi Wang committed
998 999 1000 1001 1002 1003 1004 1005
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
1006
 
Hongzhi Wang's avatar
Hongzhi Wang committed
1007

1008 1009 1010 1011
    // for tbslbrm calculation according to 5.4.2.1 of 38.212
    if (harq_process->Nl < Nl)
      Nl = harq_process->Nl;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1012
    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
1013

1014
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1015 1016 1017 1018 1019 1020 1021 1022
                                 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,
1023 1024 1025
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
      return(dlsch->max_ldpc_iterations);
    } else
    {
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }
1037

1038
 
1039
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))   
1040
    for (int i =0; i<16; i++)
1041
      LOG_I(PHY,"rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
Hongzhi Wang's avatar
Hongzhi Wang committed
1042

1043 1044 1045

  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) 
    {
1046

Hongzhi Wang's avatar
Hongzhi Wang committed
1047
    if (r==0) {
1048 1049
      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);
Hongzhi Wang's avatar
Hongzhi Wang committed
1050 1051
    }

1052
    LOG_D(PHY,"decoder input(segment %u) :",r);
1053
    for (int i=0;i<(3*8*Kr_bytes);i++)
1054 1055 1056
      LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
    LOG_D(PHY,"\n");
   }
Hongzhi Wang's avatar
Hongzhi Wang committed
1057 1058 1059

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

1060
    if (harq_process->C == 1){
1061
      if (A > NR_MAX_PDSCH_TBS)
1062 1063 1064 1065
    	crc_type = CRC24_A;
      else
    	crc_type = CRC16;

1066 1067 1068
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1069
      crc_type = CRC24_B;
1070 1071
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1072 1073

    //#ifndef __AVX2__
1074

Hongzhi Wang's avatar
Hongzhi Wang committed
1075 1076
    if (err_flag == 0) {
/*
1077
        LOG_D(PHY, "LDPC 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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1078 1079 1080
                            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_ldpc_iterations);
*/
1081

Hongzhi Wang's avatar
Hongzhi Wang committed
1082
#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
1083
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1084
#endif
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1085
      LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1086

1087
      /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
Ahmed's avatar
Ahmed committed
1088
        inv_d[cnt] = (1)*harq_process->d[r][cnt];
1089
      }*/
Ahmed's avatar
Ahmed committed
1090

1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
      //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));
      //Saturate coded bits before decoding into 8 bits values
      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
Ahmed's avatar
Ahmed committed
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119
      {
        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
      }

      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
               (int8_t*)&pl[0],
               llrProcBuf,
               p_nrLDPC_procBuf,
               p_procTime);

      nb_total_decod++;
      if (no_iteration_ldpc > 10){
        nb_error_decod++;
        ret = 1+dlsch->max_ldpc_iterations;
      }
      else {
        ret=2;
      }

1120
      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1121
        LOG_D(PHY,"Segment %u CRC OK\n",r);
Ahmed's avatar
Ahmed committed
1122 1123 1124
        ret = 2;
      }
      else {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1125
        LOG_D(PHY,"CRC NOK\n");
Ahmed's avatar
Ahmed committed
1126 1127 1128
        ret = 1+dlsch->max_ldpc_iterations;
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1129 1130 1131
    if (!nb_total_decod%10000){
        printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
    }
Ahmed's avatar
Ahmed committed
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153

      for (int m=0; m < Kr>>3; m ++)
      {
        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
      }

    /*for (int u=0; u < Kr>>3; u ++)
      {
        ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
      }


      printf("output unsigned ullrProcBuf \n");

      for (int j=0; j < Kr>>3; j ++)
      {
        printf(" %d \n", ullrProcBuf[j]);
      }
      printf(" \n");*/
    //printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);

    //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
1154 1155 1156 1157
     if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
       for (int k=0;k<32;k++)
         LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);

Hongzhi Wang's avatar
Hongzhi Wang committed
1158 1159 1160 1161 1162 1163 1164 1165

#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
1166
      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
1167 1168
      err_flag = 1;
    }
1169
  //} //loop r
Hongzhi Wang's avatar
Hongzhi Wang committed
1170 1171

  if (err_flag == 1) {
1172 1173
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
      LOG_I(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",
1174
        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);
1175 1176 1177
    harq_process->harq_ack.ack = 0;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1178 1179 1180
    harq_process->errors[harq_process->round]++;
    harq_process->round++;

1181
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1182 1183 1184 1185 1186
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
    }
    if(is_crnti)
    {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1187
    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",
1188
               phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
1189 1190 1191 1192
    }

    return((1+dlsch->max_ldpc_iterations));
  } else {
1193 1194
   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
      LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n",
1195
           phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
Hongzhi Wang's avatar
Hongzhi Wang committed
1196 1197 1198

    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
1199 1200 1201
    harq_process->harq_ack.ack = 1;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1202 1203 1204 1205 1206
    //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);

    if(is_crnti)
    {
1207
    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
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
    }
    //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);

  }

  // Reassembly of Transport block here
  offset = 0;

  /*
  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);
  */
Hongzhi Wang's avatar
Hongzhi Wang committed
1221 1222 1223
  //uint32_t wait = 0;
  
  /* while((proc->decoder_thread_available == 0) )
Hongzhi Wang's avatar
Hongzhi Wang committed
1224 1225 1226
  {
          usleep(1);
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1227
  proc->decoder_thread_available == 0;*/
1228 1229 1230 1231 1232 1233 1234

  /*notifiedFIFO_elt_t *res1=tryPullTpool(&nf, Tpool);
  if (!res1) {
	  printf("mthread trypull null\n");
	  usleep(1);
	  wait++;
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1235 1236
  
  //usleep(50);
Hongzhi Wang's avatar
Hongzhi Wang committed
1237 1238

  proc->decoder_main_available = 0;
1239 1240
  Kr = harq_process->K; //to check if same K in all segments
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
1241 1242 1243
  
  for (r=0; r<harq_process->C; r++) {

Ahmed's avatar
Ahmed committed
1244 1245 1246 1247
      memcpy(harq_process->b+offset,
               harq_process->c[r],
               Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
      offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
1248

1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
    {
    LOG_I(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
    LOG_I(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
              (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
     LOG_I(PHY,"b[0] = %p,c[%d] = %p\n",
              (void *)(uint64_t)(harq_process->b[offset]),
              harq_process->F>>3,
               (void *)(uint64_t)(harq_process->c[r]));
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1259
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1260 1261
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
1262 1263 1264 1265 1266 1267 1268 1269

  dlsch->last_iteration_cnt = ret;
  //proc->decoder_thread_available = 0;
  //proc->decoder_main_available = 0;

  return(ret);
}

1270 1271


Hongzhi Wang's avatar
Hongzhi Wang committed
1272
void nr_dlsch_decoding_process(void *arg)
Hongzhi Wang's avatar
Hongzhi Wang committed
1273
{
1274 1275 1276
	nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
    UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
    PHY_VARS_NR_UE    *phy_vars_ue   = rxtxD->UE;
Hongzhi Wang's avatar
Hongzhi Wang committed
1277
    int llr8_flag1;
1278
    int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
1279 1280 1281 1282
    t_nrLDPC_dec_params decParams;
    t_nrLDPC_dec_params* p_decParams = &decParams;
    t_nrLDPC_time_stats procTime;
    t_nrLDPC_time_stats* p_procTime =&procTime ;
1283
    int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
1284
    t_nrLDPC_procBuf* p_nrLDPC_procBuf; 
Hongzhi Wang's avatar
Hongzhi Wang committed
1285 1286 1287
    int16_t z [68*384];
    int8_t l [68*384];
    //__m128i l;
Hongzhi Wang's avatar
Hongzhi Wang committed
1288 1289
    //int16_t inv_d [68*384];
    //int16_t *p_invd =&inv_d;
1290
    uint8_t  kc;
1291
    uint8_t Ilbrm = 1;
1292 1293
    uint32_t Tbslbrm = 950984;
    uint16_t nb_rb = 30; //to update
1294
    double Coderate = 0.0;
1295 1296 1297
    uint16_t nb_symb_sch = 12;
    uint8_t nb_re_dmrs = 6;
    uint16_t length_dmrs = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1298 1299 1300 1301 1302 1303

    uint32_t i,j;
    __m128i *pv = (__m128i*)&z;
    __m128i *pl = (__m128i*)&l;

    proc->instance_cnt_dlsch_td=-1;
1304
    //proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe;
Hongzhi Wang's avatar
Hongzhi Wang committed
1305

1306
    proc->decoder_thread_available = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1307 1308 1309 1310 1311 1312 1313 1314 1315
    

#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;
1316

1317
  uint32_t ret;
1318
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bits_F;
1319

Hongzhi Wang's avatar
Hongzhi Wang committed
1320
  uint8_t crc_type;
1321 1322 1323 1324
  uint8_t C,Cprime;
  uint8_t Qm;
  uint8_t Nl;
  //uint32_t Er;
Hongzhi Wang's avatar
Hongzhi Wang committed
1325

1326 1327 1328 1329
  int eNB_id                = proc->eNB_id;
  int harq_pid              = proc->harq_pid;
  llr8_flag1                = proc->llr8_flag;
  int frame                 = proc->frame_rx;
1330
  r               	    = proc->num_seg;
Ahmed's avatar
Ahmed committed
1331

1332
  NR_UE_DLSCH_t *dlsch      = phy_vars_ue->dlsch[proc->thread_id][eNB_id][0];
1333
  NR_DL_UE_HARQ_t *harq_process  = dlsch->harq_processes[harq_pid];
1334
  short *dlsch_llr        = phy_vars_ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0];
1335

1336 1337
  p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
  nb_symb_sch = harq_process->nb_symbols;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1338
  LOG_D(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
Ahmed's avatar
Ahmed committed
1339

Hongzhi Wang's avatar
Hongzhi Wang committed
1340

1341
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
1342 1343 1344

  harq_process->trials[harq_process->round]++;

1345 1346
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs

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

Hongzhi Wang's avatar
Hongzhi Wang committed
1349 1350
  A = harq_process->TBS; //2072 for QPSK 1/3

1351

Hongzhi Wang's avatar
Hongzhi Wang committed
1352 1353
  ret = dlsch->max_ldpc_iterations;

1354
  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
1355
  G = harq_process->G;
1356

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1357
  LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
1358

Francesco Mani's avatar
Francesco Mani committed
1359
  if ((harq_process->R)<1024)
1360 1361 1362
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
1363

1364
  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25)
1365 1366
  {
    p_decParams->BG = 2;
1367
    kc = 52;
1368 1369 1370 1371
    if (Coderate < 0.3333){
      p_decParams->R = 15;
    }
    else if (Coderate <0.6667){
Ahmed's avatar
Ahmed committed
1372 1373
      p_decParams->R = 13;
    }
1374 1375 1376 1377 1378 1379
    else {
      p_decParams->R = 23;
    }
  }
  else{
    p_decParams->BG = 1;
1380
    kc = 68;
1381
    if (Coderate < 0.6667){
Ahmed's avatar
Ahmed committed
1382
      p_decParams->R = 13;
1383 1384 1385 1386 1387 1388 1389
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
    }
    else {
      p_decParams->R = 89;
    }
1390 1391
  }    

Hongzhi Wang's avatar
Hongzhi Wang committed
1392
  harq_process->round  =0;
magounak's avatar
magounak committed
1393
 // if (harq_process->round == 0) {
1394
    // This is a new packet, so compute quantities regarding segmentation
1395
  if (A > NR_MAX_PDSCH_TBS)
1396 1397 1398
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410

    nr_segmentation(NULL,
                    NULL,
                    harq_process->B,
                    &harq_process->C,
                    &harq_process->K,
                    &harq_process->Z,
                    &harq_process->F,
                    p_decParams->BG);

    p_decParams->Z = harq_process->Z;

magounak's avatar
magounak committed
1411
   // }
Hongzhi Wang's avatar
Hongzhi Wang committed
1412
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1413
    LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
1414

1415

1416
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
1417
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
1418 1419 1420 1421 1422 1423

  err_flag = 0;

  opp_enabled=1;
  
  Qm= harq_process->Qm;
1424 1425 1426
  Nl=harq_process->Nl;
  //r_thread = harq_process->C/2-1;
  C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
1427

1428
  Cprime = C; //assume CBGTI not present
Hongzhi Wang's avatar
Hongzhi Wang committed
1429

1430
  if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
Ahmed's avatar
Ahmed committed
1431
    r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
1432
  else
Ahmed's avatar
Ahmed committed
1433
    r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1434
          
Hongzhi Wang's avatar
Hongzhi Wang committed
1435
  //for (r=(harq_process->C/2); r<harq_process->C; r++) {
1436
     //    r=1; //(harq_process->C/2);
Hongzhi Wang's avatar
Hongzhi Wang committed
1437

1438
  r_offset = r*r_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
1439

1440 1441
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
1442
  K_bits_F = Kr-harq_process->F;
Hongzhi Wang's avatar
Hongzhi Wang committed
1443

1444
  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
1445 1446 1447 1448 1449 1450 1451 1452 1453

#if UE_TIMING_TRACE
    start_meas(dlsch_deinterleaving_stats);
#endif
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
                           harq_process->w[r],
                           dlsch_llr+r_offset);

1454
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
1455
    for (int i =0; i<16; i++)
1456 1457
              LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);

1458 1459 1460 1461 1462

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1463 1464 1465 1466
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

1467 1468
  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
    LOG_I(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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1469 1470 1471 1472 1473 1474 1475 1476
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
1477

Hongzhi Wang's avatar
Hongzhi Wang committed
1478

1479
    if (Nl<4)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1480
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
1481
    else
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1482
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
1483

1484
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1485 1486 1487 1488 1489 1490 1491 1492
                                 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,
1493 1494 1495
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
      //return(dlsch->max_ldpc_iterations);
    } else
    {
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

1508 1509 1510 1511 1512
    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
      LOG_D(PHY,"decoder input(segment %u) :",r);
      for (int i=0;i<(3*8*Kr_bytes)+12;i++)
        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
      LOG_D(PHY,"\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1513 1514 1515 1516 1517
    }


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

1518
    if (harq_process->C == 1){
1519
      if (A > NR_MAX_PDSCH_TBS)
1520 1521 1522 1523
    	 	crc_type = CRC24_A;
    	else
    		crc_type = CRC16;

1524 1525 1526
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1527
      crc_type = CRC24_B;
1528 1529
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1530 1531 1532

    if (err_flag == 0) {
/*
Hongzhi Wang's avatar
Hongzhi Wang committed
1533
        LOG_D(PHY, "LDPC 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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1534 1535 1536
                            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_ldpc_iterations);
*/
Ahmed's avatar
Ahmed committed
1537
      if (llr8_flag1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1538
        AssertFatal (Kr >= 256, "LDPC 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",
Ahmed's avatar
Ahmed committed
1539 1540
            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);
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1541 1542 1543
#if UE_TIMING_TRACE
        start_meas(dlsch_turbo_decoding_stats);
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1544
//      LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
1545
/*
1546 1547 1548
        for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
              inv_d[cnt] = (1)*harq_process->d[r][cnt];
              }
1549
*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1550

1551 1552 1553
        //set first 2*Z_c bits to zeros
        memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
        //set Filler bits
1554
        memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
1555
        //Move coded bits before filler bits
1556
        memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
1557 1558 1559 1560
        //skip filler bits
        memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
        //Saturate coded bits before decoding into 8 bits values
        for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
1561 1562 1563
        {
          pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
1564

1565
        no_iteration_ldpc = nrLDPC_decoder(p_decParams,
1566 1567 1568 1569
                                           (int8_t*)&pl[0],
                                           llrProcBuf,
                                           p_nrLDPC_procBuf,
                                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
1570

1571 1572
        // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
        if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
1573
          LOG_D(PHY,"Segment %u CRC OK\n",r);
1574 1575 1576
          ret = 2;
        }
        else {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1577
          LOG_D(PHY,"Segment %u CRC NOK\n",r);
1578 1579 1580
          ret = 1+dlsch->max_ldpc_iterations;
        }

Ahmed's avatar
Ahmed committed
1581
    if (no_iteration_ldpc > 10)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1582
      LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
1583

Hongzhi Wang's avatar
Hongzhi Wang committed
1584

Ahmed's avatar
Ahmed committed
1585 1586 1587 1588
    for (int m=0; m < Kr>>3; m ++)
                    {
                  harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
                    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1589

1590 1591 1592
    if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))       
      for (int k=0;k<2;k++)
        LOG_D(PHY,"segment 1 output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
Hongzhi Wang's avatar
Hongzhi Wang committed
1593

Ahmed's avatar
Ahmed committed
1594
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
#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;
//      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
      err_flag = 1;
    }
  //}

1606 1607 1608
  proc->decoder_thread_available = 1;
  //proc->decoder_main_available = 0;
}
Hongzhi Wang's avatar
Hongzhi Wang committed
1609

1610 1611 1612 1613
void *dlsch_thread(void *arg) {
  //this thread should be over the processing thread to keep in real time
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
1614 1615
  notifiedFIFO_elt_t *res_dl;
  initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1616

1617
  for (int i=0; i<tpool_nbthreads(pool_dl)+1; i++){
Hongzhi Wang's avatar
Hongzhi Wang committed
1618
    pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
Hongzhi Wang's avatar
Hongzhi Wang committed
1619
                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
Hongzhi Wang's avatar
Hongzhi Wang committed
1620

1621
  while (!oai_exit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1622

1623
    notifiedFIFO_elt_t *res;
Hongzhi Wang's avatar
Hongzhi Wang committed
1624

1625
    while (nbDlProcessing >= tpool_nbthreads(pool_dl)) {
1626
      if ( (res=tryPullTpool(&nf, &pool_dl)) != NULL ) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1627 1628
        //nbDlProcessing--;
        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
1629
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1630

1631
      usleep(200);
Hongzhi Wang's avatar
Hongzhi Wang committed
1632
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1633
    
1634
    res_dl=pullTpool(&nf, &pool_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1635 1636 1637
    nbDlProcessing--;
	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1638

1639 1640
    //msgToPush->key=0;
    //pushTpool(Tpool, msgToPush);
Hongzhi Wang's avatar
Hongzhi Wang committed
1641

1642
  } // while !oai_exit
Hongzhi Wang's avatar
Hongzhi Wang committed
1643

Hongzhi Wang's avatar
Hongzhi Wang committed
1644
  return NULL;
Hongzhi Wang's avatar
Hongzhi Wang committed
1645 1646
}

1647