nr_ulsch_decoding.c 22.5 KB
Newer Older
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 33 34 35 36 37 38 39
/*
 * 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_TRANSPORT/nr_ulsch_decoding.c
* \brief Top-level routines for decoding  LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
* \author Ahmed Hussein
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \note
* \warning
*/


// [from gNB coding]
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h"
40
#include "PHY/CODING/nrLDPC_extern.h"
41 42 43 44 45 46 47 48 49
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "SCHED_NR/sched_nr.h"
#include "defs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
#include <syscall.h>
//#define DEBUG_ULSCH_DECODING
Florian Kaltenberger's avatar
Florian Kaltenberger committed
50
//#define gNB_DEBUG_TRACE
51 52

#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
53
//#define PRINT_CRC_CHECK
54 55 56

//extern double cpuf;

57
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL)
58 59 60
{

  int i,r;
61
  uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS;  //number of segments to be allocated
62
  NR_gNB_ULSCH_t *ulsch = *ulschptr;
63

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  if (N_RB_UL != 273) {
    a_segments = a_segments*N_RB_UL;
    a_segments = a_segments/273 +1;
  }

  for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
    if (ulsch->harq_processes[i]) {
      if (ulsch->harq_processes[i]->b) {
        free_and_zero(ulsch->harq_processes[i]->b);
        ulsch->harq_processes[i]->b = NULL;
      }
      for (r=0; r<a_segments; r++) {
        free_and_zero(ulsch->harq_processes[i]->c[r]);
        free_and_zero(ulsch->harq_processes[i]->d[r]);
        free_and_zero(ulsch->harq_processes[i]->w[r]);
        nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
        ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
81
      }
82 83
      free_and_zero(ulsch->harq_processes[i]);
      ulsch->harq_processes[i] = NULL;
84 85
    }
  }
86
  free_and_zero(*ulschptr);
87 88 89
}


90
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
91 92 93
{

  NR_gNB_ULSCH_t *ulsch;
Laurent Thomas's avatar
Laurent Thomas committed
94
  uint8_t i,r;
95
  uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS;  //number of segments to be allocated
96

Francesco Mani's avatar
Francesco Mani committed
97 98
  if (N_RB_UL != 273) {
    a_segments = a_segments*N_RB_UL;
99
    a_segments = a_segments/273 +1;
100
  }
101

102
  uint32_t ulsch_bytes = a_segments*1056;  // allocated bytes per segment
103 104 105 106 107 108 109 110 111
  ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t));
  
  ulsch->max_ldpc_iterations = max_ldpc_iterations;
  ulsch->Mlimit = 4;
  
  for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
    
    ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16_clear(sizeof(NR_UL_gNB_HARQ_t));
    ulsch->harq_processes[i]->b = (uint8_t*)malloc16_clear(ulsch_bytes);
112 113 114 115 116
    for (r=0; r<a_segments; r++) {
      ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
      ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t));
      ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16_clear((68*384)*sizeof(int16_t));
      ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16_clear((3*(6144+64))*sizeof(int16_t));
117 118
    }
  }
119 120
  
  return(ulsch);
121 122
}

123 124 125 126 127
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
{
  unsigned char i, j;

  if (ulsch) {
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
    ulsch->harq_mask = 0;
    ulsch->bundling = 0;
    ulsch->beta_offset_cqi_times8 = 0;
    ulsch->beta_offset_ri_times8 = 0;
    ulsch->beta_offset_harqack_times8 = 0;
    ulsch->Msg3_active = 0;
    ulsch->Msg3_flag = 0;
    ulsch->Msg3_subframe = 0;
    ulsch->Msg3_frame = 0;
    ulsch->rnti = 0;
    ulsch->rnti_type = 0;
    ulsch->cyclicShift = 0;
    ulsch->cooperation_flag = 0;
    ulsch->Mlimit = 0;
    ulsch->max_ldpc_iterations = 0;
    ulsch->last_iteration_cnt = 0;
    for (i=0;i<NR_MAX_SLOTS_PER_FRAME;i++) ulsch->harq_process_id[i] = 0;

    for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
      if (ulsch->harq_processes[i]){
        /// Nfapi ULSCH PDU
        //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
        ulsch->harq_processes[i]->frame=0;
151
        ulsch->harq_processes[i]->slot=0;
152 153 154 155 156
        ulsch->harq_processes[i]->round=0;
        ulsch->harq_processes[i]->TPC=0;
        ulsch->harq_processes[i]->mimo_mode=0;
        ulsch->harq_processes[i]->dci_alloc=0;
        ulsch->harq_processes[i]->rar_alloc=0;
157
        ulsch->harq_processes[i]->status=NR_SCH_IDLE;
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
        ulsch->harq_processes[i]->subframe_scheduling_flag=0;
        ulsch->harq_processes[i]->previous_first_rb=0;
        ulsch->harq_processes[i]->handled=0;
        ulsch->harq_processes[i]->delta_TF=0;

        ulsch->harq_processes[i]->TBS=0;
        /// Pointer to the payload (38.212 V15.4.0 section 5.1)
        //uint8_t *b;
        ulsch->harq_processes[i]->B=0;
        /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
        //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
        ulsch->harq_processes[i]->K=0;
        ulsch->harq_processes[i]->F=0;
        ulsch->harq_processes[i]->C=0;
        /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
        //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
        /// LDPC processing buffer
        //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
        ulsch->harq_processes[i]->Z=0;
        /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
        //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
        ulsch->harq_processes[i]->E=0;


        ulsch->harq_processes[i]->n_DMRS=0;
        ulsch->harq_processes[i]->n_DMRS2=0;
        ulsch->harq_processes[i]->previous_n_DMRS=0;


        ulsch->harq_processes[i]->cqi_crc_status=0;
        for (j=0;j<MAX_CQI_BYTES;j++) ulsch->harq_processes[i]->o[j]=0;
        ulsch->harq_processes[i]->uci_format=0;
        ulsch->harq_processes[i]->Or1=0;
        ulsch->harq_processes[i]->Or2=0;
        ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0;
        ulsch->harq_processes[i]->O_RI=0;
        ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0;
        ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0;
        ulsch->harq_processes[i]->O_ACK=0;
        ulsch->harq_processes[i]->V_UL_DAI=0;
        /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
        //int8_t q[MAX_CQI_PAYLOAD];
        ulsch->harq_processes[i]->o_RCC=0;
        /// coded and interleaved CQI bits
        //int8_t o_w[(MAX_CQI_BITS+8)*3];
        /// coded CQI bits
        //int8_t o_d[96+((MAX_CQI_BITS+8)*3)];
        for (j=0;j<MAX_ACK_PAYLOAD;j++) ulsch->harq_processes[i]->q_ACK[j]=0;
        for (j=0;j<MAX_RI_PAYLOAD;j++) ulsch->harq_processes[i]->q_RI[j]=0;
        /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
        //uint8_t h[MAX_NUM_CHANNEL_BITS];
        /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
210
        //int16_t w[MAX_NUM_NR_ULSCH_SEGMENTS][3*(6144+64)];
211 212
      }
    }
213 214
  }
}
215

216 217 218 219
#ifdef PRINT_CRC_CHECK
  static uint32_t prnt_crc_cnt = 0;
#endif

220
void nr_processULSegment(void* arg) {
221 222 223
  ldpcDecode_t *rdata = (ldpcDecode_t*) arg;
  PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
  NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
224
  t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
225
  int length_dec;
Sakthi's avatar
Sakthi committed
226
  int no_iteration_ldpc;
227 228
  int Kr;
  int Kr_bytes;
229
  int K_bits_F;
230 231 232 233 234 235 236 237 238 239
  uint8_t crc_type;
  int i;
  int j;
  int r = rdata->segment_r;
  int A = rdata->A;
  int E = rdata->E;
  int Qm = rdata->Qm;
  int rv_index = rdata->rv_index;
  int r_offset = rdata->r_offset;
  uint8_t kc = rdata->Kc;
Sakthi's avatar
Sakthi committed
240
  uint32_t Tbslbrm = rdata->Tbslbrm;
241
  short* ulsch_llr = rdata->ulsch_llr;
242
  int max_ldpc_iterations = p_decoderParms->numMaxIter;
243
  int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
244

245 246
  int16_t  z [68*384 + 16] __attribute__ ((aligned(16)));
  int8_t   l [68*384 + 16] __attribute__ ((aligned(16)));
Sakthi's avatar
Sakthi committed
247 248 249 250

  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
  
251 252 253 254
  uint8_t  Ilbrm    = 0;

  Kr = ulsch_harq->K;
  Kr_bytes = Kr>>3;
255
  K_bits_F = Kr-ulsch_harq->F;
256

257
  t_nrLDPC_time_stats procTime = {0};
Sakthi's avatar
Sakthi committed
258 259
  t_nrLDPC_time_stats* p_procTime     = &procTime ;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
260
  //start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278

  ////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////

  //////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////

  nr_deinterleaving_ldpc(E,
                         Qm,
                         ulsch_harq->e[r],
                         ulsch_llr+r_offset);

  //for (int i =0; i<16; i++)
  //          printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset);

  stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);


279 280
  /*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,
281 282 283
        Kr*3,
        ulsch_harq->TBS,
        Qm,
284 285 286 287
        nb_rb,
        n_layers,
        pusch_pdu->pusch_data.rv_index,
        ulsch_harq->round);*/
288 289 290 291 292 293 294 295 296
  //////////////////////////////////////////////////////////////////////////////////////////


  //////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////

  ///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////

Sakthivel Velumani's avatar
Sakthivel Velumani committed
297
  //start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
298 299 300

  if (nr_rate_matching_ldpc_rx(Ilbrm,
                               Tbslbrm,
Sakthi's avatar
Sakthi committed
301 302
                               p_decoderParms->BG,
                               p_decoderParms->Z,
303 304 305 306
                               ulsch_harq->d[r],
                               ulsch_harq->e[r],
                               ulsch_harq->C,
                               rv_index,
307
                               ulsch_harq->new_rx,
308
                               E,
francescomani's avatar
francescomani committed
309 310
                               ulsch_harq->F,
                               Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335

    stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);

    LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
    rdata->decodeIterations = max_ldpc_iterations + 1;
    return;
  } else {
    stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
  }

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

  if (ulsch_harq->C == 1) {
    if (A > 3824)
      crc_type = CRC24_A;
    else
      crc_type = CRC16;

    length_dec = ulsch_harq->B;
  }
  else {
    crc_type = CRC24_B;
    length_dec = (ulsch_harq->B+24*ulsch_harq->C)/ulsch_harq->C;
  }

Sakthivel Velumani's avatar
Sakthivel Velumani committed
336
  //start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
337

338 339 340 341 342 343 344 345 346 347 348
  //set first 2*Z_c bits to zeros
  memset(&z[0],0,2*ulsch_harq->Z*sizeof(int16_t));
  //set Filler bits
  memset((&z[0]+K_bits_F),127,ulsch_harq->F*sizeof(int16_t));
  //Move coded bits before filler bits
  memcpy((&z[0]+2*ulsch_harq->Z),ulsch_harq->d[r],(K_bits_F-2*ulsch_harq->Z)*sizeof(int16_t));
  //skip filler bits
  memcpy((&z[0]+Kr),ulsch_harq->d[r]+(Kr-2*ulsch_harq->Z),(kc*ulsch_harq->Z-Kr)*sizeof(int16_t));
  //Saturate coded bits before decoding into 8 bits values
  for (i=0, j=0; j < ((kc*ulsch_harq->Z)>>4)+1;  i+=2, j++)
  {
349 350 351 352 353 354 355 356 357 358
    pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
  }
  //////////////////////////////////////////////////////////////////////////////////////////


  //////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////

  ////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
359

360
  no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
361 362 363 364
                                     (int8_t*)&pl[0],
                                     llrProcBuf,
                                     ulsch_harq->p_nrLDPC_procBuf[r],
                                     p_procTime);
365

366 367
  if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
368
      LOG_I(PHY, "Segment %d CRC OK, iterations %d/%d\n",r,no_iteration_ldpc,max_ldpc_iterations);
369 370
#endif
    rdata->decodeIterations = no_iteration_ldpc;
371
    if (rdata->decodeIterations > p_decoderParms->numMaxIter) rdata->decodeIterations--;
372 373 374 375 376 377 378 379 380 381
  } else {
#ifdef PRINT_CRC_CHECK
      LOG_I(PHY, "CRC NOK\n");
#endif
    rdata->decodeIterations = max_ldpc_iterations + 1;
  }

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

  //stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
384 385
}

386
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
387
                           uint8_t ULSCH_id,
388 389
                           short *ulsch_llr,
                           NR_DL_FRAME_PARMS *frame_parms,
390
                           nfapi_nr_pusch_pdu_t *pusch_pdu,
391 392 393
                           uint32_t frame,
                           uint8_t nr_tti_rx,
                           uint8_t harq_pid,
394 395
                           uint32_t G) {

396
  uint32_t A;
Sakthi's avatar
Sakthi committed
397 398 399 400 401 402
  uint32_t r;
  uint32_t r_offset;
  uint32_t offset;
  int kc;
  int Tbslbrm;
  int E;
403 404 405 406 407 408 409 410 411 412 413
  int8_t llrProcBuf[22*384];
  int ret = 0;
  int i,j;
  int8_t enable_ldpc_offload = 1;
  int16_t  z_ol [68*384];
  int8_t   l_ol [68*384];
  __m128i *pv_ol128 = (__m128i*)&z_ol;
  __m128i *pl_ol128 = (__m128i*)&l_ol;
  int no_iteration_ldpc;
  int length_dec;
  uint8_t crc_type;
414 415 416
#ifdef PRINT_CRC_CHECK
  prnt_crc_cnt++;
#endif
417 418
  

419 420
  NR_gNB_ULSCH_t                       *ulsch                 = phy_vars_gNB->ulsch[ULSCH_id][0];
  NR_gNB_PUSCH                         *pusch                 = phy_vars_gNB->pusch_vars[ULSCH_id];
421
  NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
422 423 424 425 426 427

  if (!harq_process) {
    LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
    return 1;
  }

428 429
  t_nrLDPC_dec_params decParams;
  t_nrLDPC_dec_params* p_decParams    = &decParams;
Sakthi's avatar
Sakthi committed
430

Sakthivel Velumani's avatar
Sakthivel Velumani committed
431 432
  int Kr;
  int Kr_bytes;
Sakthi's avatar
Sakthi committed
433 434
    
  phy_vars_gNB->nbDecode = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
435
  harq_process->processedSegments = 0;
Sakthi's avatar
Sakthi committed
436

yilmazt's avatar
yilmazt committed
437
  double   Coderate = 0.0;
438 439
  
  // ------------------------------------------------------------------
440 441 442 443 444
  uint16_t nb_rb          = pusch_pdu->rb_size;
  uint8_t Qm              = pusch_pdu->qam_mod_order;
  uint16_t R              = pusch_pdu->target_code_rate;
  uint8_t mcs             = pusch_pdu->mcs_index;
  uint8_t n_layers        = pusch_pdu->nrOfLayers;
445
  // ------------------------------------------------------------------
446 447

   if (!ulsch_llr) {
Sakthi's avatar
Sakthi committed
448
    LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
449
    return 1;
450 451
  }

Rakesh's avatar
Rakesh committed
452
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
453
  harq_process->TBS = pusch_pdu->pusch_data.tb_size;
454
  harq_process->round = nr_rv_to_round(pusch_pdu->pusch_data.rv_index);
455

456 457 458 459
  harq_process->new_rx = false; // flag to indicate if this is a new reception for this harq (initialized to false)
  if (harq_process->round == 0) {
    harq_process->new_rx = true;
    harq_process->ndi = pusch_pdu->pusch_data.new_data_indicator;
460
  }
461 462 463 464 465 466 467 468

  // this happens if there was a DTX in round 0
  if (harq_process->ndi != pusch_pdu->pusch_data.new_data_indicator) {
    harq_process->new_rx = true;
    harq_process->ndi = pusch_pdu->pusch_data.new_data_indicator;
    LOG_E(PHY,"Missed ULSCH detection. NDI toggled but rv %d does not correspond to first reception\n",pusch_pdu->pusch_data.rv_index);
  }

469
  A   = (harq_process->TBS)<<3;
470

471
  LOG_D(NR_PHY, "ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d, Coderate %d\n", harq_pid, A, G, mcs, n_layers, nb_rb, Qm, n_layers, R);
472

Raymond Knopp's avatar
Raymond Knopp committed
473 474 475 476 477 478 479
  if (R<1024)
    Coderate = (float) R /(float) 1024;
  else
    Coderate = (float) R /(float) 2048;
  
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
    p_decParams->BG = 2;
480
    kc = 52;
Raymond Knopp's avatar
Raymond Knopp committed
481
    if (Coderate < 0.3333) {
482 483 484 485 486 487 488 489 490 491
      p_decParams->R = 15;
    }
    else if (Coderate <0.6667) {
      p_decParams->R = 13;
    }
    else {
      p_decParams->R = 23;
    }
  } else {
    p_decParams->BG = 1;
492
    kc = 68;
493 494 495 496 497 498 499 500 501
    if (Coderate < 0.6667) {
      p_decParams->R = 13;
    }
    else if (Coderate <0.8889) {
      p_decParams->R = 23;
    }
    else {
      p_decParams->R = 89;
    }
502
  }
Raymond Knopp's avatar
Raymond Knopp committed
503
  
504 505 506
  NR_gNB_SCH_STATS_t *stats=NULL;
  int first_free=-1;
  for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
507
    if (phy_vars_gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
508
      first_free = i;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
509
      stats=&phy_vars_gNB->ulsch_stats[i];
510
    }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
511 512
    if (phy_vars_gNB->ulsch_stats[i].rnti == ulsch->rnti) {
      stats=&phy_vars_gNB->ulsch_stats[i];
513 514 515 516
      break;
    }
  }
  if (stats) {
517
    stats->frame = frame;
518 519
    stats->rnti = ulsch->rnti;
    stats->round_trials[harq_process->round]++;
520 521 522 523
    for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
       stats->power[aarx]=dB_fixed_x10(pusch->ulsch_power[aarx]);
       stats->noise_power[aarx]=dB_fixed_x10(pusch->ulsch_noise_power[aarx]);
    }
524
    if (harq_process->new_rx == 0) {
525 526 527 528
      stats->current_Qm = Qm;
      stats->current_RI = n_layers;
      stats->total_bytes_tx += harq_process->TBS;
    }
529 530 531 532 533
  }
  if (A > 3824)
    harq_process->B = A+24;
  else
    harq_process->B = A+16;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
534

535
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
536 537 538 539 540 541 542 543
  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);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
544 545

#ifdef DEBUG_ULSCH_DECODING
546 547 548
  printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
  if (!frame%100)
    printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
549
#endif
Sakthivel Velumani's avatar
Sakthivel Velumani committed
550
  Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers);
Sakthi's avatar
Sakthi committed
551

Sakthivel Velumani's avatar
Sakthivel Velumani committed
552 553 554
  p_decParams->Z = harq_process->Z;


555 556 557 558 559
  p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
  p_decParams->outMode= 0;

  r_offset = 0;

560
  uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS;  //number of segments to be allocated
561

Francesco Mani's avatar
Francesco Mani committed
562 563
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
564
    a_segments = a_segments/273 +1;
565
  }
566

567 568
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
569
    return 1;
570 571 572 573
  }
#ifdef DEBUG_ULSCH_DECODING
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif
Sakthivel Velumani's avatar
Sakthivel Velumani committed
574 575 576
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
  offset = 0;
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629

  if (enable_ldpc_offload) {
  memset(harq_process->c[0],0,Kr_bytes);

  if (harq_process->C == 1) {
    if (A > 3824)
      crc_type = CRC24_A;
    else
      crc_type = CRC16;

    length_dec = harq_process->B;
  }
  else {
    crc_type = CRC24_B;
    length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
  }


  E = nr_get_E(G, harq_process->C, Qm, n_layers, 0);

  memcpy((&z_ol[0]),ulsch_llr,G*sizeof(int16_t));
  
  for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
  {
    pl_ol128[j] = _mm_packs_epi16(pv_ol128[i],pv_ol128[i+1]);
  }
 
  ret = nrLDPC_decoder_offload(p_decParams,
			harq_process->C, 
			pusch_pdu->pusch_data.rv_index,
			harq_process->F,
			E,
			Qm,
 			(int8_t*)&pl_ol128[0],
			llrProcBuf);

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

  if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
      LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif
    no_iteration_ldpc = 2;
  } else {
#ifdef PRINT_CRC_CHECK
      LOG_I(PHY, "CRC NOK\n");
#endif
    no_iteration_ldpc = ulsch->max_ldpc_iterations + 1;
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
630
      	/*for (int k=0;k<8;k++)
631 632 633 634
        {
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
        printf("llrprocbuf [%d] =  %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k);
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
635
  */ 
636 637 638 639 640 641 642 643 644 645 646

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

     }

 
  } 
  else { 
647
  void (*nr_processULSegment_ptr)(void*) = &nr_processULSegment;
648 649

  for (r=0; r<harq_process->C; r++) {
Sakthi's avatar
Sakthi committed
650

651
    E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
652
printf("rm length %d seg %d\n", E,r);
Sakthi's avatar
Sakthi committed
653
    union ldpcReqUnion id = {.s={ulsch->rnti,frame,nr_tti_rx,0,0}};
654
    notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, phy_vars_gNB->respDecode, nr_processULSegment_ptr);
655 656 657 658
    ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);

    rdata->gNB = phy_vars_gNB;
    rdata->ulsch_harq = harq_process;
659
    rdata->decoderParms = decParams;
660
    rdata->ulsch_llr = ulsch_llr;
Sakthi's avatar
Sakthi committed
661
    rdata->Kc = kc;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
662
    rdata->harq_pid = harq_pid;
663 664 665 666 667 668
    rdata->segment_r = r;
    rdata->nbSegments = harq_process->C;
    rdata->E = E;
    rdata->A = A;
    rdata->Qm = Qm;
    rdata->r_offset = r_offset;
Sakthi's avatar
Sakthi committed
669
    rdata->Kr_bytes = Kr_bytes;
670 671
    rdata->rv_index = pusch_pdu->pusch_data.rv_index;
    rdata->Tbslbrm = Tbslbrm;
Sakthi's avatar
Sakthi committed
672 673
    rdata->offset = offset;
    rdata->ulsch = ulsch;
674
    rdata->ulsch_id = ULSCH_id;
Sakthi's avatar
Sakthi committed
675 676 677
    pushTpool(phy_vars_gNB->threadPool,req);
    phy_vars_gNB->nbDecode++;
    LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode);
678
    r_offset += E;
Sakthi's avatar
Sakthi committed
679
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
680 681
    //////////////////////////////////////////////////////////////////////////////////////////
  }
682
  } 
683
  return 1;
684
}