nr_dlsch_decoding.c 56.6 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"
Hongzhi Wang's avatar
Hongzhi Wang committed
47
//#define DEBUG_DLSCH_DECODING
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

Hongzhi Wang's avatar
Hongzhi Wang committed
59 60
//extern double cpuf;

61
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
Hongzhi Wang's avatar
Hongzhi Wang committed
62 63 64
{

  int i,r;
65
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
66
  NR_UE_DLSCH_t *dlsch=*dlschptr;
Hongzhi Wang's avatar
Hongzhi Wang committed
67 68

  if (dlsch) {
69 70 71 72 73 74
    if (N_RB_DL != 273) {
      a_segments = a_segments*N_RB_DL;
      a_segments = a_segments/273;
    }  
 

Hongzhi Wang's avatar
Hongzhi Wang committed
75 76 77
    for (i=0; i<dlsch->Mdlharq; i++) {
      if (dlsch->harq_processes[i]) {
        if (dlsch->harq_processes[i]->b) {
laurent's avatar
laurent committed
78
          free16(dlsch->harq_processes[i]->b,a_segments*1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
79 80 81
          dlsch->harq_processes[i]->b = NULL;
        }

82
        for (r=0; r<a_segments; r++) {
83
          free16(dlsch->harq_processes[i]->c[r],1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
84 85 86
          dlsch->harq_processes[i]->c[r] = NULL;
        }

87
        for (r=0; r<a_segments; r++)
Hongzhi Wang's avatar
Hongzhi Wang committed
88
          if (dlsch->harq_processes[i]->d[r]) {
89
            free16(dlsch->harq_processes[i]->d[r],(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
90 91
            dlsch->harq_processes[i]->d[r] = NULL;
          }
92
        
93 94
        for (r=0; r<a_segments; r++)
          if (dlsch->harq_processes[i]->w[r]) {
95
            free16(dlsch->harq_processes[i]->w[r],(5*8448)*sizeof(short));
96 97 98
            dlsch->harq_processes[i]->w[r] = NULL;
          }

99
        for (r=0; r<a_segments; r++) {
Ahmed's avatar
Ahmed committed
100 101 102 103 104
          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
105 106 107 108 109

        free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
      }
    }
110
      
Hongzhi Wang's avatar
Hongzhi Wang committed
111 112 113 114 115
    free16(dlsch,sizeof(NR_UE_DLSCH_t));
    dlsch = NULL;
  }
}

116
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
117 118 119 120 121
{

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

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

Francesco Mani's avatar
Francesco Mani committed
124 125
  if (N_RB_DL != 273) {
    a_segments = a_segments*N_RB_DL;
126
    a_segments = (a_segments/273)+1;
127
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
128

129
  uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
Hongzhi Wang's avatar
Hongzhi Wang committed
130 131 132 133 134 135 136

  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
137
    dlsch->number_harq_processes_for_pdsch = Mdlharq;
Hongzhi Wang's avatar
Hongzhi Wang committed
138
    dlsch->Nsoft = Nsoft;
139
    dlsch->Mlimit = 4;
Hongzhi Wang's avatar
Hongzhi Wang committed
140
    dlsch->max_ldpc_iterations = max_ldpc_iterations;
141
 
Hongzhi Wang's avatar
Hongzhi Wang committed
142 143 144 145 146 147
    for (i=0; i<Mdlharq; i++) {
      //      printf("new_ue_dlsch: Harq process %d\n",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
148
        init_downlink_harq_status(dlsch->harq_processes[i]);
Hongzhi Wang's avatar
Hongzhi Wang committed
149
        dlsch->harq_processes[i]->first_tx=1;
150
        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
151 152

        if (dlsch->harq_processes[i]->b)
153
          memset(dlsch->harq_processes[i]->b,0,dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
154 155 156 157
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
158
          for (r=0; r<a_segments; r++) { 
Ahmed's avatar
Ahmed committed
159
            dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
Hongzhi Wang's avatar
Hongzhi Wang committed
160
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
161 162

            if (dlsch->harq_processes[i]->c[r])
Hongzhi Wang's avatar
Hongzhi Wang committed
163
              memset(dlsch->harq_processes[i]->c[r],0,1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
164 165 166
            else
              exit_flag=2;

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

            if (dlsch->harq_processes[i]->d[r])
170
              memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
171 172
            else
              exit_flag=2;
173

174
            dlsch->harq_processes[i]->w[r] = (short*)malloc16((5*8448)*sizeof(short));
175 176

            if (dlsch->harq_processes[i]->w[r])
177
              memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
178 179
            else
              exit_flag=2;
Hongzhi Wang's avatar
Hongzhi Wang committed
180 181 182 183 184 185 186 187 188 189 190 191
          }
        }
      } else {
        exit_flag=1;
      }
    }

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

  printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
192
  free_nr_ue_dlsch(&dlsch,N_RB_DL);
Hongzhi Wang's avatar
Hongzhi Wang committed
193 194 195 196

  return(NULL);
}

Hongzhi Wang's avatar
Hongzhi Wang committed
197
void nr_dlsch_unscrambling(int16_t* llr,
hongzhi wang's avatar
hongzhi wang committed
198
                         uint32_t size,
Hongzhi Wang's avatar
Hongzhi Wang committed
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
                         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
215
      llr[i] = -llr[i];
Hongzhi Wang's avatar
Hongzhi Wang committed
216 217 218 219
  }

}

220
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
221 222 223 224 225 226 227 228 229 230
			   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_tti_rx,
			   uint8_t harq_pid,
			   uint8_t is_crnti,
			   uint8_t llr8_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
231 232 233 234 235 236 237 238 239 240
{

#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;
241
  int32_t no_iteration_ldpc, length_dec;
242
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
Hongzhi Wang's avatar
Hongzhi Wang committed
243
  uint8_t crc_type;
244
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
Hongzhi Wang's avatar
Hongzhi Wang committed
245 246 247 248
  t_nrLDPC_dec_params decParams;
  t_nrLDPC_dec_params* p_decParams = &decParams;
  t_nrLDPC_time_stats procTime;
  t_nrLDPC_time_stats* p_procTime =&procTime ;
249 250 251 252 253
  
  if (!harq_process) {
    printf("dlsch_decoding.c: NULL harq_process pointer\n");
    return(dlsch->max_ldpc_iterations + 1);
  }
254
  t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
255

256
    
Hongzhi Wang's avatar
Hongzhi Wang committed
257 258 259
  int16_t z [68*384];
  int8_t l [68*384];
  //__m128i l;
260
  //int16_t inv_d [68*384];
261
  uint8_t kc;
Hongzhi Wang's avatar
Hongzhi Wang committed
262
  uint8_t Ilbrm = 0;
263 264 265 266

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

268
  uint8_t dmrs_Type = harq_process->dmrsConfigType;
269
  AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type);
270
  uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; // should be changed based on MAC parameters
271
  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
Raymond Knopp's avatar
Raymond Knopp committed
272
  AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
Hongzhi Wang's avatar
Hongzhi Wang committed
273 274 275 276 277

  uint32_t i,j;

  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
Hongzhi Wang's avatar
Hongzhi Wang committed
278 279
  
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
280

281 282
  //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];

Ahmed's avatar
Ahmed committed
283
  if (!dlsch_llr) {
Hongzhi Wang's avatar
Hongzhi Wang committed
284
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
285
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
286 287 288 289
  }

  if (!frame_parms) {
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
290
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
291 292
  }

293
  /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
294
    printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
295
    return(dlsch->max_ldpc_iterations + 1);
296
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
297

298
  /*if (harq_process->harq_ack.ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
299 300
    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_tti_rx, harq_process->harq_ack.ack);
301
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
302 303 304 305 306 307

  //  nb_rb = dlsch->nb_rb;

  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
308
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
309 310 311 312 313
    }*/

  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
314
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
315 316 317
  }
  */

318 319
  nb_rb = harq_process->nb_rb;

Hongzhi Wang's avatar
Hongzhi Wang committed
320 321
  harq_process->trials[harq_process->round]++;

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

Hongzhi Wang's avatar
Hongzhi Wang committed
326
  A = harq_process->TBS;
327
  ret = dlsch->max_ldpc_iterations + 1;
328
  dlsch->last_iteration_cnt = ret;
329
 
Raymond Knopp's avatar
Raymond Knopp committed
330
  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
331 332
  G = harq_process->G;

333
  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
334

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

Ahmed's avatar
Ahmed committed
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
  {
    p_decParams->BG = 2;
    if (Coderate < 0.3333){
      p_decParams->R = 15;
      kc = 52;
    }
    else if (Coderate <0.6667){
      p_decParams->R = 13;
      kc = 32;
    }
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
      p_decParams->R = 13;
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
  }

372 373 374

  if (harq_process->round == 0) {
    // This is a new packet, so compute quantities regarding segmentation
375 376 377 378 379
	if (A > 3824)
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;

380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
    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);

#ifdef DEBUG_DLSCH_DECODING
    if (!frame%100)
      printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
#endif
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
395
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
396 397 398 399

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

Ahmed's avatar
Ahmed committed
400 401 402 403
  //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
404 405 406 407

  err_flag = 0;
  r_offset = 0;

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

Francesco Mani's avatar
Francesco Mani committed
410 411
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
412 413
    a_segments = a_segments/273;
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
414

415 416
  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
417 418
    return((1+dlsch->max_ldpc_iterations));
  }
Ahmed's avatar
Ahmed committed
419

Hongzhi Wang's avatar
Hongzhi Wang committed
420
#ifdef DEBUG_DLSCH_DECODING
421
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
422 423 424 425
#endif

  opp_enabled=1;

Ahmed's avatar
Ahmed committed
426
  Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
Hongzhi Wang's avatar
Hongzhi Wang committed
427 428
  Kr_bytes = Kr>>3;

Hongzhi Wang's avatar
Hongzhi Wang committed
429 430
  K_bytes_F = Kr_bytes-(harq_process->F>>3);

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

433
    //printf("start rx segment %d\n",r);
434 435 436 437 438
    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
439

Hongzhi Wang's avatar
Hongzhi Wang committed
440
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
441

442

443 444
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
Ahmed's avatar
Ahmed committed
445
                           harq_process->w[r], // [hna] w is e
446 447
                           dlsch_llr+r_offset);

Hongzhi Wang's avatar
Hongzhi Wang committed
448
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
449

450
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
451
    //          printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
452 453 454 455

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif
456

Hongzhi Wang's avatar
Hongzhi Wang committed
457 458 459 460
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

461 462
    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
463 464 465 466 467 468 469
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
470

Hongzhi Wang's avatar
Hongzhi Wang committed
471

Hongzhi Wang's avatar
Hongzhi Wang committed
472
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
473

474 475 476 477 478
    if ((harq_process->Nl)<4)
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
    else
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);

479

Hongzhi Wang's avatar
Hongzhi Wang committed
480
    if (nr_rate_matching_ldpc_rx(Ilbrm,
481 482 483 484 485 486 487 488
                                 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,
489
                                 E,
cig's avatar
cig committed
490 491
                                 harq_process->F,
                                 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
492
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
493 494 495 496
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
497
      return(dlsch->max_ldpc_iterations + 1);
Ahmed's avatar
Ahmed committed
498
    } else {
499

Hongzhi Wang's avatar
Hongzhi Wang committed
500 501 502 503 504
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

505

506
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
507
    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
Hongzhi Wang's avatar
Hongzhi Wang committed
508

509
    r_offset += E;
510

Hongzhi Wang's avatar
Hongzhi Wang committed
511 512
#ifdef DEBUG_DLSCH_DECODING
    if (r==0) {
Ahmed's avatar
Ahmed committed
513
      write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
514
      write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
515 516
    }

517
    printf("decoder input(segment %u) :",r);
Ahmed's avatar
Ahmed committed
518
    int i;
519
    for (i=0;i<E;i++)
Hongzhi Wang's avatar
Hongzhi Wang committed
520
      printf("%d : %d\n",i,harq_process->d[r][i]);
Ahmed's avatar
Ahmed committed
521
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
522 523 524 525 526 527
#endif

    //    printf("Clearing c, %p\n",harq_process->c[r]);
    memset(harq_process->c[r],0,Kr_bytes);

    //    printf("done\n");
528
    if (harq_process->C == 1){
529 530 531 532 533 534 535
    	if (A > 3824) 
    		crc_type = CRC24_A;
    	else
    		crc_type = CRC16;
    	
	length_dec = harq_process->B;

536 537
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
538
      crc_type = CRC24_B;
539 540
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
541 542 543 544

    if (err_flag == 0) {

#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
545
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
546 547
#endif

548
      //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
Hongzhi Wang's avatar
Hongzhi Wang committed
549

550
      //printf("harq process dr iteration %d\n", p_decParams->numMaxIter);
Hongzhi Wang's avatar
Hongzhi Wang committed
551

Ahmed's avatar
Ahmed committed
552 553 554
      memset(pv,0,2*harq_process->Z*sizeof(int16_t));
      //memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
      memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
Hongzhi Wang's avatar
Hongzhi Wang committed
555

556

Ahmed's avatar
Ahmed committed
557 558 559 560
      for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
      {
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
      }
561 562 563 564
      // Kbytes_F = Kr_bytes - F>>3
      j+=(harq_process->F>>3);
      //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
      for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
Ahmed's avatar
Ahmed committed
565 566 567 568 569 570 571 572 573
      {
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
      }

      for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
      {
        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
      }

cig's avatar
cig committed
574

Hongzhi Wang's avatar
Hongzhi Wang committed
575
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
576

Ahmed's avatar
Ahmed committed
577 578 579
      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                           (int8_t*)&pl[0],
                           llrProcBuf,
580
                           p_nrLDPC_procBuf[r],
581
                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
582
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
583

Ahmed's avatar
Ahmed committed
584 585
      // 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)) {
586
        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
587 588
        //Temporary hack
        no_iteration_ldpc = dlsch->max_ldpc_iterations;
589
        ret = no_iteration_ldpc;
Ahmed's avatar
Ahmed committed
590 591
      }
      else {
592
        LOG_D(PHY,"CRC NOK\n\033[0m");
593
        ret = 1 + dlsch->max_ldpc_iterations;
Ahmed's avatar
Ahmed committed
594 595
      }

596

Ahmed's avatar
Ahmed committed
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
      nb_total_decod++;
      if (no_iteration_ldpc > dlsch->max_ldpc_iterations){
        nb_error_decod++;
      }

      //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);
      //}
      //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);

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

613
#ifdef DEBUG_DLSCH_DECODING
hongzhi wang's avatar
hongzhi wang committed
614
      //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]);
Guy De Souza's avatar
Guy De Souza committed
615
      for (int k=0;k<A>>3;k++)
Ahmed's avatar
Ahmed committed
616
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
617
      printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
618
      //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
619
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
620 621 622 623 624 625


#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }
626 627
    
    
Hongzhi Wang's avatar
Hongzhi Wang committed
628 629 630 631 632 633 634 635 636 637

    /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
                  harq_process->C,
                  r,
                  dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
                  dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
                  dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/


    if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
638
      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
Hongzhi Wang's avatar
Hongzhi Wang committed
639 640 641 642 643 644 645 646 647 648 649 650 651
      err_flag = 1;
    }
  }

  int32_t frame_rx_prev = frame;
  int32_t tti_rx_prev = nr_tti_rx - 1;
  if (tti_rx_prev < 0) {
    frame_rx_prev--;
    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
  }
  frame_rx_prev = frame_rx_prev%1024;

  if (err_flag == 1) {
652
//#if UE_DEBUG_TRACE
653
    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",
Hongzhi Wang's avatar
Hongzhi Wang committed
654
        phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
655
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
656 657 658 659
    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]++;
660
    // harq_process->round++; // [hna] uncomment this line when HARQ is implemented
Hongzhi Wang's avatar
Hongzhi Wang committed
661 662

    //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
663
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
664 665 666
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
    }
667

Hongzhi Wang's avatar
Hongzhi Wang committed
668 669
    if(is_crnti)
    {
670
    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
671 672 673
               phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
    }

674
    return((1 + dlsch->max_ldpc_iterations));
Hongzhi Wang's avatar
Hongzhi Wang committed
675
  } else {
676
//#if UE_DEBUG_TRACE
677
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
678
	  phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
679
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
680 681 682 683 684 685

    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;
686
    
687
    //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
688 689 690 691
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);

    if(is_crnti)
    {
692
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
693 694 695 696 697 698 699
    }
    //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
700 701
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
702 703 704 705 706 707

  /*
  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);
  */
708

Hongzhi Wang's avatar
Hongzhi Wang committed
709
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
710

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

Hongzhi Wang's avatar
Hongzhi Wang committed
713
    memcpy(harq_process->b+offset,
714 715
	   harq_process->c[r],
	   Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
Hongzhi Wang's avatar
Hongzhi Wang committed
716 717 718
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));

#ifdef DEBUG_DLSCH_DECODING
719
    printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
720 721 722 723 724 725
    printf("copied %d bytes to b sequence (harq_pid %d)\n",
              (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
              printf("b[0] = %x,c[%d] = %x\n",
              harq_process->b[offset],
              harq_process->F>>3,
              harq_process->c[r]);
726 727 728 729 730

              /*printf ("Printing payload bytes:");
                for (int i = 0; i < Kr_bytes; i++){
                printf("%d : %d \n", i, harq_process->b[i]);
                }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
731
#endif
732 733

#if defined(ENABLE_PHY_PAYLOAD_DEBUG)
734
           if (frame%100 == 0){
735
              LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
736
              for (int i = 0; i <10 ; i++){ //Kr_bytes
737
            	  LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]);
738 739
              }
          }
Hongzhi Wang's avatar
Hongzhi Wang committed
740 741
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
742 743
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
744
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
745

Hongzhi Wang's avatar
Hongzhi Wang committed
746 747 748 749 750 751
  dlsch->last_iteration_cnt = ret;

  return(ret);
}

#ifdef UE_DLSCH_PARALLELISATION
752
uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Ahmed's avatar
Ahmed committed
753 754 755 756 757 758 759 760 761 762 763 764
                                    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_tti_rx,
                                    uint8_t harq_pid,
                                    uint8_t is_crnti,
                                    uint8_t llr8_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
765 766 767 768 769 770 771 772 773 774
{

#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;
775
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bytes_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
776 777
  uint8_t crc_type;
  //UE_rxtx_proc_t *proc = &phy_vars_ue->proc;
778
  int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
779 780 781 782 783
  /*uint8_t C;
  uint8_t Qm;
  uint8_t r_thread;
  uint32_t Er, Gp,GpmodC;*/
  t_nrLDPC_dec_params decParams;
784 785 786
  t_nrLDPC_dec_params* p_decParams = &decParams;
  t_nrLDPC_time_stats procTime;
  t_nrLDPC_time_stats* p_procTime =&procTime ;
787
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
788 789 790 791
    if (!harq_process) {
    printf("dlsch_decoding.c: NULL harq_process pointer\n");
    return(dlsch->max_ldpc_iterations);
  }
792
  t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
793
  uint8_t Nl=4;
794 795 796
  int16_t z [68*384];
  int8_t l [68*384];
  //__m128i l;
Hongzhi Wang's avatar
Hongzhi Wang committed
797
  //int16_t inv_d [68*384];
798 799
  //int16_t *p_invd =&inv_d;
  uint8_t kb, kc;
800
  uint8_t Ilbrm = 1;
801
  uint32_t Tbslbrm = 950984;
802 803
  uint16_t nb_rb = 30;
  double Coderate = 0.0;
Hongzhi Wang's avatar
Hongzhi Wang committed
804
  uint8_t dmrs_type = harq_process->dmrsConfigType;
cig's avatar
cig committed
805 806 807
  //nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
  //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;

808
  uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4;
Raymond Knopp's avatar
Raymond Knopp committed
809
  uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); 
Hongzhi Wang's avatar
Hongzhi Wang committed
810

811
  uint32_t i,j;
Hongzhi Wang's avatar
Hongzhi Wang committed
812
//  int nbDlProcessing =0;
Hongzhi Wang's avatar
Hongzhi Wang committed
813

814 815 816 817
  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
818

Hongzhi Wang's avatar
Hongzhi Wang committed
819
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
820 821 822 823 824 825

  if (!dlsch_llr) {
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
    return(dlsch->max_ldpc_iterations);
  }

826

Hongzhi Wang's avatar
Hongzhi Wang committed
827 828 829 830 831 832

  if (!frame_parms) {
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
    return(dlsch->max_ldpc_iterations);
  }

833
 /* if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
834 835 836 837 838 839 840
    printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
    return(dlsch->max_ldpc_iterations);
  }

  if (dlsch->harq_ack[nr_tti_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_tti_rx, dlsch->harq_ack[nr_tti_rx].ack);
841
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
842 843 844 845 846 847 848 849 850 851 852 853 854 855

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

  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
    return(max_ldpc_iterations);
  }
  */

856
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
857 858
  harq_process->trials[harq_process->round]++;

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

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

863
  A = harq_process->TBS;
Hongzhi Wang's avatar
Hongzhi Wang committed
864

Hongzhi Wang's avatar
Hongzhi Wang committed
865 866
  ret = dlsch->max_ldpc_iterations + 1;
  dlsch->last_iteration_cnt = ret;
Hongzhi Wang's avatar
Hongzhi Wang committed
867

868
  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
869 870 871

  G = harq_process->G;

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

Hongzhi Wang's avatar
Hongzhi Wang committed
874 875 876 877 878 879 880
  proc->decoder_main_available = 1;
  proc->decoder_thread_available = 0;
  proc->decoder_thread_available1 = 0;
  //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);

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

Francesco Mani's avatar
Francesco Mani committed
881
  if ((harq_process->R)<1024)
882 883 884
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
885

886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
  {
    p_decParams->BG = 2;
    if (Coderate < 0.3333){
      p_decParams->R = 15;
      kc = 52;
    }
    else if (Coderate <0.6667){
      p_decParams->R = 13;
      kc = 32;
    }
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
      p_decParams->R = 13;
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
917

918 919
  if (harq_process->round == 0) {
      // This is a new packet, so compute quantities regarding segmentation
920 921 922 923 924
	  if (A > 3824)
	  	  harq_process->B = A+24;
	  else
	  	  harq_process->B = A+16;

925 926 927 928 929 930 931 932 933 934 935
      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
936 937
    
    p_decParams->Z = harq_process->Z;
938

939 940 941
  //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
942 943 944 945

  err_flag = 0;
  r_offset = 0;

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

Francesco Mani's avatar
Francesco Mani committed
948 949
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
950 951
    a_segments = a_segments/273;
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
952

953 954
  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
955 956 957
    return((1+dlsch->max_ldpc_iterations));
  }
#ifdef DEBUG_DLSCH_DECODING
958
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
959 960
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
961
  notifiedFIFO_elt_t *res_dl;
Hongzhi Wang's avatar
Hongzhi Wang committed
962
  opp_enabled=1;
963 964
  if (harq_process->C>1) {
	for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
Hongzhi Wang's avatar
Hongzhi Wang committed
965 966
	  if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
	          pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
967 968
	        }

Hongzhi Wang's avatar
Hongzhi Wang committed
969 970
	  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);
971
	  curMsg->UE=phy_vars_ue;
Hongzhi Wang's avatar
Hongzhi Wang committed
972 973 974
	  
	  nbDlProcessing++;

975 976 977 978 979 980 981 982 983 984

	  memset(&curMsg->proc, 0, sizeof(curMsg->proc));
	  curMsg->proc.frame_rx  = proc->frame_rx;
	  curMsg->proc.nr_tti_rx = proc->nr_tti_rx;
	  curMsg->proc.num_seg   = nb_seg;

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

Hongzhi Wang's avatar
Hongzhi Wang committed
985 986
	  msgToPush_dl->key= (nr_tti_rx%2) ? (nb_seg+30): nb_seg;
	  pushTpool(Tpool_dl, msgToPush_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
987

Ahmed's avatar
Ahmed committed
988 989 990 991
  /*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
992

Ahmed's avatar
Ahmed committed
993 994
    Gp = G/Nl/Qm;
    GpmodC = Gp%C;
Hongzhi Wang's avatar
Hongzhi Wang committed
995 996


Ahmed's avatar
Ahmed committed
997 998 999 1000 1001
    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
1002

Ahmed's avatar
Ahmed committed
1003
    printf("mthread instance_cnt_dlsch_td %d\n",  proc->instance_cnt_dlsch_td);*/
1004
	  }
Ahmed's avatar
Ahmed committed
1005 1006 1007 1008 1009
  //proc->decoder_main_available = 1;
  }

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

1011
    Kr = harq_process->K;
Hongzhi Wang's avatar
Hongzhi Wang committed
1012
    Kr_bytes = Kr>>3;
1013
    K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1014

1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
    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);

#ifdef DEBUG_DLSCH_DECODING
        for (int i =0; i<16; i++)
1032
              printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1033 1034 1035 1036 1037 1038
#endif

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

#ifdef DEBUG_DLSCH_DECODING
    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
          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);
#endif

1055 1056 1057 1058
    // for tbslbrm calculation according to 5.4.2.1 of 38.212
    if (harq_process->Nl < Nl)
      Nl = harq_process->Nl;

Hongzhi Wang's avatar
Hongzhi Wang committed
1059
    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
1060

1061
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1062 1063 1064 1065 1066 1067 1068 1069
                                 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,
1070 1071 1072
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
#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
    }
1084 1085

    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
1086
    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
1087

1088
    //r_offset += E;
Hongzhi Wang's avatar
Hongzhi Wang committed
1089
    //printf("main thread r_offset %d\n",r_offset);
1090 1091 1092
 
#ifdef DEBUG_DLSCH_DECODING   
    for (int i =0; i<16; i++)
1093
      printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
1094
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1095 1096

#ifdef DEBUG_DLSCH_DECODING
1097

Hongzhi Wang's avatar
Hongzhi Wang committed
1098
    if (r==0) {
Ahmed's avatar
Ahmed committed
1099 1100
      write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
      write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
1101 1102
    }

1103
    printf("decoder input(segment %u) :",r);
1104 1105
    for (int i=0;i<(3*8*Kr_bytes);i++)
      printf("%d : %d\n",i,harq_process->d[r][i]);
Ahmed's avatar
Ahmed committed
1106
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1107 1108 1109 1110 1111 1112 1113
#endif


    //    printf("Clearing c, %p\n",harq_process->c[r]);
    memset(harq_process->c[r],0,Kr_bytes);

    //    printf("done\n");
1114
    if (harq_process->C == 1){
1115 1116 1117 1118 1119
      if (A > 3824)
    	crc_type = CRC24_A;
      else
    	crc_type = CRC16;

1120 1121 1122
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1123
      crc_type = CRC24_B;
1124 1125
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1126 1127

    //#ifndef __AVX2__
1128

Hongzhi Wang's avatar
Hongzhi Wang committed
1129 1130
    if (err_flag == 0) {
/*
1131
        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
1132 1133 1134
                            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);
*/
1135

Hongzhi Wang's avatar
Hongzhi Wang committed
1136
#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
1137
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1138
#endif
1139
      LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1140

1141
      /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
Ahmed's avatar
Ahmed committed
1142
        inv_d[cnt] = (1)*harq_process->d[r][cnt];
1143
      }*/
Ahmed's avatar
Ahmed committed
1144 1145 1146 1147 1148 1149

      memset(pv,0,2*p_decParams->Z*sizeof(int16_t));
      //memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
      memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));


1150
      for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
Ahmed's avatar
Ahmed committed
1151
      {
1152
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1153 1154
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1155 1156 1157
      j+=(harq_process->F>>3);
      //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
      for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
Ahmed's avatar
Ahmed committed
1158
      {
1159
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1160
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1161
      
Ahmed's avatar
Ahmed committed
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
      for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
      {
        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;
      }

1182
      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
1183
        printf("Segment %u CRC OK\n",r);
Ahmed's avatar
Ahmed committed
1184 1185 1186 1187 1188 1189 1190
        ret = 2;
      }
      else {
        printf("CRC NOK\n");
        ret = 1+dlsch->max_ldpc_iterations;
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1191 1192 1193
    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
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218

    //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);

      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]);
1219
#ifdef DEBUG_DLSCH_DECODING
Ahmed's avatar
Ahmed committed
1220 1221
      for (int k=0;k<32;k++)
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
1222
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233

#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,nr_tti_rx,r,harq_process->C-1);
      err_flag = 1;
    }
1234
  //} //loop r
Hongzhi Wang's avatar
Hongzhi Wang committed
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245

  int32_t frame_rx_prev = frame;
  int32_t tti_rx_prev = nr_tti_rx - 1;
  if (tti_rx_prev < 0) {
    frame_rx_prev--;
    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
  }
  frame_rx_prev = frame_rx_prev%1024;

  if (err_flag == 1) {
#if UE_DEBUG_TRACE
1246
    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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1247 1248
        phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
#endif
1249 1250 1251
    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
1252 1253 1254 1255 1256
    harq_process->errors[harq_process->round]++;
    harq_process->round++;


    //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
1257
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1258 1259 1260 1261 1262 1263
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
    }
    if(is_crnti)
    {
    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
1264
               phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
1265 1266 1267 1268 1269
    }

    return((1+dlsch->max_ldpc_iterations));
  } else {
#if UE_DEBUG_TRACE
1270
      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
1271 1272 1273 1274 1275
           phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
#endif

    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
1276 1277 1278
    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
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
    //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)
    {
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
    }
    //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
1298 1299 1300
  //uint32_t wait = 0;
  
  /* while((proc->decoder_thread_available == 0) )
Hongzhi Wang's avatar
Hongzhi Wang committed
1301 1302 1303
  {
          usleep(1);
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1304
  proc->decoder_thread_available == 0;*/
1305 1306 1307 1308 1309 1310 1311

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

  proc->decoder_main_available = 0;
1316 1317
  Kr = harq_process->K; //to check if same K in all segments
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
1318 1319 1320
  
  for (r=0; r<harq_process->C; r++) {

Ahmed's avatar
Ahmed committed
1321 1322 1323 1324
      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));
1325 1326

#ifdef DEBUG_DLSCH_DECODING
1327
      printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Ahmed's avatar
Ahmed committed
1328 1329 1330 1331 1332 1333
      printf("copied %d bytes to b sequence (harq_pid %d)\n",
                (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
                printf("b[0] = %x,c[%d] = %x\n",
                harq_process->b[offset],
                harq_process->F>>3,
                harq_process->c[r]);
1334
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1335
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1336 1337
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347

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

  return(ret);
}
#endif

#ifdef UE_DLSCH_PARALLELISATION
Hongzhi Wang's avatar
Hongzhi Wang committed
1348
void nr_dlsch_decoding_process(void *arg)
Hongzhi Wang's avatar
Hongzhi Wang committed
1349
{
1350 1351 1352
	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;
1353
    NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
Hongzhi Wang's avatar
Hongzhi Wang committed
1354
    int llr8_flag1;
1355
    int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
1356 1357 1358 1359
    t_nrLDPC_dec_params decParams;
    t_nrLDPC_dec_params* p_decParams = &decParams;
    t_nrLDPC_time_stats procTime;
    t_nrLDPC_time_stats* p_procTime =&procTime ;
1360
    int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
1361
    t_nrLDPC_procBuf* p_nrLDPC_procBuf; 
Hongzhi Wang's avatar
Hongzhi Wang committed
1362 1363 1364
    int16_t z [68*384];
    int8_t l [68*384];
    //__m128i l;
Hongzhi Wang's avatar
Hongzhi Wang committed
1365 1366
    //int16_t inv_d [68*384];
    //int16_t *p_invd =&inv_d;
1367
    uint8_t kb, kc;
1368
    uint8_t Ilbrm = 1;
1369 1370
    uint32_t Tbslbrm = 950984;
    uint16_t nb_rb = 30; //to update
1371
    double Coderate = 0.0;
1372 1373 1374
    uint16_t nb_symb_sch = 12;
    uint8_t nb_re_dmrs = 6;
    uint16_t length_dmrs = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1375 1376 1377 1378 1379 1380 1381 1382

    uint32_t i,j;
    uint32_t k;

    __m128i *pv = (__m128i*)&z;
    __m128i *pl = (__m128i*)&l;

    proc->instance_cnt_dlsch_td=-1;
1383
    //proc->nr_tti_rx=proc->sub_frame_start;
Hongzhi Wang's avatar
Hongzhi Wang committed
1384

1385
    proc->decoder_thread_available = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
    

#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;
1396
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
1397
  uint8_t crc_type;
1398 1399 1400 1401
  uint8_t C,Cprime;
  uint8_t Qm;
  uint8_t Nl;
  //uint32_t Er;
Hongzhi Wang's avatar
Hongzhi Wang committed
1402

1403 1404 1405 1406
  int eNB_id                = proc->eNB_id;
  int harq_pid              = proc->harq_pid;
  llr8_flag1                = proc->llr8_flag;
  int frame                 = proc->frame_rx;
1407 1408
  int slot                  = proc->nr_tti_rx;
  r               	    = proc->num_seg;
Ahmed's avatar
Ahmed committed
1409

1410 1411 1412 1413 1414 1415
  NR_UE_DLSCH_t *dlsch      = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0];
  NR_DL_UE_HARQ_t *harq_process  = dlsch->harq_processes[harq_pid];
  short *dlsch_llr        = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[slot]][eNB_id]->llr[0];
  //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag);
  p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
  nb_symb_sch = harq_process->nb_symbols;
1416
  printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols);
Ahmed's avatar
Ahmed committed
1417

Hongzhi Wang's avatar
Hongzhi Wang committed
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431

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

  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
    return(max_ldpc_iterations);
  }
  */

1432
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
1433 1434 1435

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

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

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

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

1442

Hongzhi Wang's avatar
Hongzhi Wang committed
1443 1444
  ret = dlsch->max_ldpc_iterations;

1445
  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
1446
  G = harq_process->G;
1447

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

Francesco Mani's avatar
Francesco Mani committed
1450
  if ((harq_process->R)<1024)
1451 1452 1453
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
1454

1455 1456 1457 1458 1459 1460 1461 1462
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
  {
    p_decParams->BG = 2;
    if (Coderate < 0.3333){
      p_decParams->R = 15;
      kc = 52;
    }
    else if (Coderate <0.6667){
Ahmed's avatar
Ahmed committed
1463
      p_decParams->R = 13;
1464
      kc = 32;
Ahmed's avatar
Ahmed committed
1465
    }
1466 1467 1468 1469 1470 1471 1472 1473
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
Ahmed's avatar
Ahmed committed
1474
      p_decParams->R = 13;
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
1485 1486
  }    

Hongzhi Wang's avatar
Hongzhi Wang committed
1487
  harq_process->round  =0;
magounak's avatar
magounak committed
1488
 // if (harq_process->round == 0) {
1489
    // This is a new packet, so compute quantities regarding segmentation
1490 1491 1492 1493
	if (A > 3824)
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;
1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505

    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
1506
   // }
Hongzhi Wang's avatar
Hongzhi Wang committed
1507 1508
    
    //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
1509

1510

1511
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
1512
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523

  /*
  else {
    printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
    return(max_ldpc_iterations);
  }
  */
  err_flag = 0;
  //r_offset = 0;

  /*
1524
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
1525

Francesco Mani's avatar
Francesco Mani committed
1526 1527
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
1528 1529
    a_segments = a_segments/273;
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
1530

1531 1532
  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
1533 1534 1535 1536 1537 1538 1539 1540 1541
    return((1+dlsch->max_ldpc_iterations));
  }*/
#ifdef DEBUG_DLSCH_DECODING
  printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
#endif

  opp_enabled=1;
  
  Qm= harq_process->Qm;
1542 1543 1544
  Nl=harq_process->Nl;
  //r_thread = harq_process->C/2-1;
  C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
1545

1546
  Cprime = C; //assume CBGTI not present
Hongzhi Wang's avatar
Hongzhi Wang committed
1547

1548
  if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
Ahmed's avatar
Ahmed committed
1549
    r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
1550
  else
Ahmed's avatar
Ahmed committed
1551
    r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1552

Ahmed's avatar
Ahmed committed
1553 1554
    //  printf("thread0 r_offset %d\n",r_offset);
           
Hongzhi Wang's avatar
Hongzhi Wang committed
1555
  //for (r=(harq_process->C/2); r<harq_process->C; r++) {
1556
     //    r=1; //(harq_process->C/2);
Hongzhi Wang's avatar
Hongzhi Wang committed
1557

1558
  r_offset = r*r_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
1559

1560 1561 1562
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
  K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1563

1564
  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
1565 1566 1567 1568 1569 1570 1571 1572 1573

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

1574 1575
#ifdef DEBUG_DLSCH_DECODING
    for (int i =0; i<16; i++)
1576
              printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1577
#endif
1578 1579 1580 1581 1582

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

#ifdef DEBUG_DLSCH_DECODING
    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
          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);
#endif

1599 1600 1601 1602 1603
    if (Nl<4)
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
    else
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);

1604
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1605 1606 1607 1608 1609 1610 1611 1612
                                 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,
1613 1614 1615
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627
#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
    }

1628
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
1629
    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
1630

1631
    //r_offset += E;
1632

1633
#ifdef DEBUG_DLSCH_DECODING
Hongzhi Wang's avatar
Hongzhi Wang committed
1634 1635
    if (r==0) {
              write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
1636
              write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
1637 1638
    }

1639
    printf("decoder input(segment %u) :",r);
Hongzhi Wang's avatar
Hongzhi Wang committed
1640
    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
1641 1642
      printf("%d : %d\n",i,harq_process->d[r][i]);
      printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1643 1644 1645 1646 1647 1648
#endif


    //    printf("Clearing c, %p\n",harq_process->c[r]);
    memset(harq_process->c[r],0,Kr_bytes);

1649
    if (harq_process->C == 1){
1650 1651 1652 1653 1654
    	if (A > 3824)
    	 	crc_type = CRC24_A;
    	else
    		crc_type = CRC16;

1655 1656 1657
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1658
      crc_type = CRC24_B;
1659 1660
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1661 1662 1663

    if (err_flag == 0) {
/*
1664
        LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
1665 1666 1667
                            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
1668 1669 1670 1671
      if (llr8_flag1) {
        AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
            Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1672 1673 1674 1675
#if UE_TIMING_TRACE
        start_meas(dlsch_turbo_decoding_stats);
#endif
//      LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
1676
/*
1677 1678 1679
        for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
              inv_d[cnt] = (1)*harq_process->d[r][cnt];
              }
1680
*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1681

1682 1683 1684
        memset(pv,0,2*p_decParams->Z*sizeof(int16_t));
        //memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
        memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
Hongzhi Wang's avatar
Hongzhi Wang committed
1685

1686
        for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
Ahmed's avatar
Ahmed committed
1687
        {
1688
          pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1689
        }
1690

Hongzhi Wang's avatar
Hongzhi Wang committed
1691 1692 1693
        j+=(harq_process->F>>3);
        //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
        for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
1694
        {
Hongzhi Wang's avatar
Hongzhi Wang committed
1695
         pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
1696
        }
1697

1698 1699 1700 1701
        for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
        {
          pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
1702

1703
        no_iteration_ldpc = nrLDPC_decoder(p_decParams,
1704 1705 1706 1707
                                           (int8_t*)&pl[0],
                                           llrProcBuf,
                                           p_nrLDPC_procBuf,
                                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
1708

1709 1710
        // 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)) {
1711
          LOG_D(PHY,"Segment %u CRC OK\n",r);
1712 1713 1714
          ret = 2;
        }
        else {
1715
          LOG_D(PHY,"Segment %u CRC NOK\n",r);
1716 1717 1718
          ret = 1+dlsch->max_ldpc_iterations;
        }

Ahmed's avatar
Ahmed committed
1719
    if (no_iteration_ldpc > 10)
1720
      LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
Ahmed's avatar
Ahmed committed
1721 1722
    //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
Hongzhi Wang's avatar
Hongzhi Wang committed
1723

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

Ahmed's avatar
Ahmed committed
1729 1730 1731 1732
            /*for (int u=0; u < Kr>>3; u ++)
                            {
                      ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
                            }
Hongzhi Wang's avatar
Hongzhi Wang committed
1733 1734


Ahmed's avatar
Ahmed committed
1735
            printf("output unsigned ullrProcBuf \n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1736

Ahmed's avatar
Ahmed committed
1737 1738
            for (int j=0; j < Kr>>3; j ++)
                                    {
Hongzhi Wang's avatar
Hongzhi Wang committed
1739

Ahmed's avatar
Ahmed committed
1740
                              printf(" %d \n", ullrProcBuf[j]);
Hongzhi Wang's avatar
Hongzhi Wang committed
1741

Ahmed's avatar
Ahmed committed
1742 1743 1744 1745 1746
                                    }
          printf(" \n");*/
#ifdef DEBUG_DLSCH_DECODING       
  for (int k=0;k<2;k++)
      printf("segment 1 output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
1747
#endif 
Ahmed's avatar
Ahmed committed
1748
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759
#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;
    }
  //}

1760 1761 1762
  proc->decoder_thread_available = 1;
  //proc->decoder_main_available = 0;
}
Hongzhi Wang's avatar
Hongzhi Wang committed
1763

1764 1765 1766 1767 1768
void *dlsch_thread(void *arg) {
  //this thread should be over the processing thread to keep in real time
  PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
1769 1770
  notifiedFIFO_elt_t *res_dl;
  initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1771

Hongzhi Wang's avatar
Hongzhi Wang committed
1772
  for (int i=0; i<RX_NB_TH_DL+1; i++){
Hongzhi Wang's avatar
Hongzhi Wang committed
1773
    pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
Hongzhi Wang's avatar
Hongzhi Wang committed
1774
                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
Hongzhi Wang's avatar
Hongzhi Wang committed
1775

1776
  while (!oai_exit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1777

1778
    notifiedFIFO_elt_t *res;
Hongzhi Wang's avatar
Hongzhi Wang committed
1779

1780
    while (nbDlProcessing >= RX_NB_TH_DL) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1781
      if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
1782
        nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
Hongzhi Wang's avatar
Hongzhi Wang committed
1783 1784
        //nbDlProcessing--;
        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
1785
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1786

1787
      usleep(200);
Hongzhi Wang's avatar
Hongzhi Wang committed
1788
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1789 1790 1791 1792 1793
    
    res_dl=pullTpool(&nf, Tpool_dl);
    nbDlProcessing--;
	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1794

1795 1796
    //msgToPush->key=0;
    //pushTpool(Tpool, msgToPush);
Hongzhi Wang's avatar
Hongzhi Wang committed
1797

1798
  } // while !oai_exit
Hongzhi Wang's avatar
Hongzhi Wang committed
1799

Hongzhi Wang's avatar
Hongzhi Wang committed
1800
  return NULL;
Hongzhi Wang's avatar
Hongzhi Wang committed
1801 1802 1803
}

#endif