nr_ulsch_decoding.c 22.3 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,uint8_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

  if (ulsch) {
65 66
    if (N_RB_UL != 273) {
      a_segments = a_segments*N_RB_UL;
67
      a_segments = a_segments/273 +1;
68 69 70
    }  


71 72 73 74
    for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {

      if (ulsch->harq_processes[i]) {
        if (ulsch->harq_processes[i]->b) {
laurent's avatar
laurent committed
75
          free16(ulsch->harq_processes[i]->b,a_segments*1056);
76 77
          ulsch->harq_processes[i]->b = NULL;
        }
78
        for (r=0; r<a_segments; r++) {
79 80 81
          free16(ulsch->harq_processes[i]->c[r],(8448)*sizeof(uint8_t));
          ulsch->harq_processes[i]->c[r] = NULL;
        }
82
        for (r=0; r<a_segments; r++) {
83 84 85 86 87
          if (ulsch->harq_processes[i]->d[r]) {
            free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t));
            ulsch->harq_processes[i]->d[r] = NULL;
          }
        }
88 89 90 91 92 93
        for (r=0; r<a_segments; r++) {
          if (ulsch->harq_processes[i]->w[r]) {
            free16(ulsch->harq_processes[i]->w[r],(3*(6144+64))*sizeof(int16_t));
            ulsch->harq_processes[i]->w[r] = NULL;
          }
        }
94
        for (r=0; r<a_segments; r++) {
95 96 97 98 99 100 101 102 103 104
          if (ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
            nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
            ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
          }
        }
        free16(ulsch->harq_processes[i],sizeof(NR_UL_gNB_HARQ_t));
        ulsch->harq_processes[i] = NULL;
      }
    }
    free16(ulsch,sizeof(NR_gNB_ULSCH_t));
105
    *ulschptr = NULL;
106 107 108 109
  }
}


110
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag)
111 112 113 114
{

  NR_gNB_ULSCH_t *ulsch;
  uint8_t exit_flag = 0,i,r;
115
  uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS;  //number of segments to be allocated
116

Francesco Mani's avatar
Francesco Mani committed
117 118
  if (N_RB_UL != 273) {
    a_segments = a_segments*N_RB_UL;
119
    a_segments = a_segments/273 +1;
120
  }
121

122
  uint16_t ulsch_bytes = a_segments*1056;  // allocated bytes per segment
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
  ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t));

  if (ulsch) {

    memset(ulsch,0,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(sizeof(NR_UL_gNB_HARQ_t));

      if (ulsch->harq_processes[i]) {

        memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t));

140
        ulsch->harq_processes[i]->b = (uint8_t*)malloc16(ulsch_bytes);
141 142

        if (ulsch->harq_processes[i]->b)
143
          memset(ulsch->harq_processes[i]->b,0,ulsch_bytes);
144 145 146 147
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
148
          for (r=0; r<a_segments; r++) {
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164

            ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();

            ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448*sizeof(uint8_t));

            if (ulsch->harq_processes[i]->c[r])
              memset(ulsch->harq_processes[i]->c[r],0,8448*sizeof(uint8_t));
            else
              exit_flag=2;

            ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16((68*384)*sizeof(int16_t));

            if (ulsch->harq_processes[i]->d[r])
              memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t));
            else
              exit_flag=2;
165 166 167 168 169 170 171

            ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16((3*(6144+64))*sizeof(int16_t));

            if (ulsch->harq_processes[i]->w[r])
              memset(ulsch->harq_processes[i]->w[r],0,(3*(6144+64))*sizeof(int16_t));
            else
              exit_flag=2;
172 173 174 175 176 177 178 179 180 181
          }
        }
      } else {
        exit_flag=1;
      }
    }

    if (exit_flag==0)
      return(ulsch);
  }
182
  printf("new_gNB_ulsch with size %zu: exit_flag = %hhu\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag);
183
  free_gNB_ulsch(&ulsch,N_RB_UL);
184 185 186
  return(NULL);
}

187 188 189 190 191
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
{
  unsigned char i, j;

  if (ulsch) {
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    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;
215
        ulsch->harq_processes[i]->slot=0;
216 217 218 219 220
        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;
221
        ulsch->harq_processes[i]->status=NR_SCH_IDLE;
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
        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)
274
        //int16_t w[MAX_NUM_NR_ULSCH_SEGMENTS][3*(6144+64)];
275 276
      }
    }
277 278
  }
}
279

280 281 282 283
#ifdef PRINT_CRC_CHECK
  static uint32_t prnt_crc_cnt = 0;
#endif

284
void nr_processULSegment(void* arg) {
285 286 287
  ldpcDecode_t *rdata = (ldpcDecode_t*) arg;
  PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
  NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
288
  t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
289
  int length_dec;
Sakthi's avatar
Sakthi committed
290
  int no_iteration_ldpc;
291 292
  int Kr;
  int Kr_bytes;
293
  int K_bits_F;
294 295 296 297 298 299 300 301 302 303
  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
304
  uint32_t Tbslbrm = rdata->Tbslbrm;
305
  short* ulsch_llr = rdata->ulsch_llr;
306
  int max_ldpc_iterations = p_decoderParms->numMaxIter;
307 308
  int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));

309 310
  int16_t  z [68*384 + 16] __attribute__ ((aligned(16)));
  int8_t   l [68*384 + 16] __attribute__ ((aligned(16)));
Sakthi's avatar
Sakthi committed
311 312 313 314

  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
  
315 316 317 318
  uint8_t  Ilbrm    = 0;

  Kr = ulsch_harq->K;
  Kr_bytes = Kr>>3;
319
  K_bits_F = Kr-ulsch_harq->F;
320

321
  t_nrLDPC_time_stats procTime = {0};
Sakthi's avatar
Sakthi committed
322 323
  t_nrLDPC_time_stats* p_procTime     = &procTime ;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
324
  //start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360

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


  /*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,
        ulsch_harq->TBS,
        Qm,
        nb_rb,
        n_layers,
        pusch_pdu->pusch_data.rv_index,
        ulsch_harq->round);*/
  //////////////////////////////////////////////////////////////////////////////////////////


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

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

Sakthivel Velumani's avatar
Sakthivel Velumani committed
361
  //start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
362 363 364

  if (nr_rate_matching_ldpc_rx(Ilbrm,
                               Tbslbrm,
Sakthi's avatar
Sakthi committed
365 366
                               p_decoderParms->BG,
                               p_decoderParms->Z,
367 368 369 370
                               ulsch_harq->d[r],
                               ulsch_harq->e[r],
                               ulsch_harq->C,
                               rv_index,
371
                               ulsch_harq->new_rx,
372 373
                               E,
       ulsch_harq->F,
Sakthi's avatar
Sakthi committed
374
       Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399

    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
400
  //start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
401

402 403 404 405 406 407 408 409 410 411 412
  //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++)
  {
413 414 415 416 417 418 419 420 421 422 423
    pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
  }
  //////////////////////////////////////////////////////////////////////////////////////////


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

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

Sakthi's avatar
Sakthi committed
424
  no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
425 426 427 428 429 430 431
                                     (int8_t*)&pl[0],
                                     llrProcBuf,
                                     ulsch_harq->p_nrLDPC_procBuf[r],
                                     p_procTime);

  if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
432
      LOG_I(PHY, "Segment %d CRC OK, iterations %d/%d\n",r,no_iteration_ldpc,max_ldpc_iterations);
433 434
#endif
    rdata->decodeIterations = no_iteration_ldpc;
435
    if (rdata->decodeIterations > p_decoderParms->numMaxIter) rdata->decodeIterations--;
436 437 438 439 440 441 442 443 444 445 446
  } 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];
  }

Sakthivel Velumani's avatar
Sakthivel Velumani committed
447
  //stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
448 449
}

450
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
451
                           uint8_t ULSCH_id,
452 453
                           short *ulsch_llr,
                           NR_DL_FRAME_PARMS *frame_parms,
454
                           nfapi_nr_pusch_pdu_t *pusch_pdu,
455 456 457
                           uint32_t frame,
                           uint8_t nr_tti_rx,
                           uint8_t harq_pid,
458 459
                           uint32_t G) {

460
  uint32_t A;
Sakthi's avatar
Sakthi committed
461 462 463 464 465 466
  uint32_t r;
  uint32_t r_offset;
  uint32_t offset;
  int kc;
  int Tbslbrm;
  int E;
467

468 469 470
#ifdef PRINT_CRC_CHECK
  prnt_crc_cnt++;
#endif
471 472
  

473 474
  NR_gNB_ULSCH_t                       *ulsch                 = phy_vars_gNB->ulsch[ULSCH_id][0];
  NR_gNB_PUSCH                         *pusch                 = phy_vars_gNB->pusch_vars[ULSCH_id];
475
  NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
476 477 478 479 480 481

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

482 483
  t_nrLDPC_dec_params decParams;
  t_nrLDPC_dec_params* p_decParams    = &decParams;
Sakthi's avatar
Sakthi committed
484

Sakthivel Velumani's avatar
Sakthivel Velumani committed
485 486
  int Kr;
  int Kr_bytes;
Sakthi's avatar
Sakthi committed
487 488
    
  phy_vars_gNB->nbDecode = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
489
  harq_process->processedSegments = 0;
Sakthi's avatar
Sakthi committed
490

yilmazt's avatar
yilmazt committed
491
  double   Coderate = 0.0;
492 493
  
  // ------------------------------------------------------------------
494 495 496 497 498
  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;
499
  // ------------------------------------------------------------------
500 501

   if (!ulsch_llr) {
Sakthi's avatar
Sakthi committed
502
    LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
503
    return 1;
504 505
  }

Rakesh's avatar
Rakesh committed
506
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
507
  harq_process->TBS = pusch_pdu->pusch_data.tb_size;
508 509
  harq_process->round = nr_rv_round_map[pusch_pdu->pusch_data.rv_index];

510 511 512 513
  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;
514
  }
515 516 517 518 519 520 521 522

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

523
  A   = (harq_process->TBS)<<3;
524

525
  LOG_D(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);
526

Raymond Knopp's avatar
Raymond Knopp committed
527 528 529 530 531 532 533
  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;
534
    kc = 52;
Raymond Knopp's avatar
Raymond Knopp committed
535
    if (Coderate < 0.3333) {
536 537 538 539 540 541 542 543 544 545
      p_decParams->R = 15;
    }
    else if (Coderate <0.6667) {
      p_decParams->R = 13;
    }
    else {
      p_decParams->R = 23;
    }
  } else {
    p_decParams->BG = 1;
546
    kc = 68;
547 548 549 550 551 552 553 554 555
    if (Coderate < 0.6667) {
      p_decParams->R = 13;
    }
    else if (Coderate <0.8889) {
      p_decParams->R = 23;
    }
    else {
      p_decParams->R = 89;
    }
556
  }
Raymond Knopp's avatar
Raymond Knopp committed
557
  
558 559 560
  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
561
    if (phy_vars_gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
562
      first_free = i;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
563
      stats=&phy_vars_gNB->ulsch_stats[i];
564
    }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
565 566
    if (phy_vars_gNB->ulsch_stats[i].rnti == ulsch->rnti) {
      stats=&phy_vars_gNB->ulsch_stats[i];
567 568 569 570
      break;
    }
  }
  if (stats) {
571
    stats->frame = frame;
572 573
    stats->rnti = ulsch->rnti;
    stats->round_trials[harq_process->round]++;
574 575 576 577
    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]);
    }
578
    if (harq_process->new_rx == 0) {
579 580 581 582
      stats->current_Qm = Qm;
      stats->current_RI = n_layers;
      stats->total_bytes_tx += harq_process->TBS;
    }
583 584 585 586 587
  }
  if (A > 3824)
    harq_process->B = A+24;
  else
    harq_process->B = A+16;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
588

589
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
590 591 592 593 594 595 596 597
  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
598 599

#ifdef DEBUG_ULSCH_DECODING
600 601 602
  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
603
#endif
Sakthivel Velumani's avatar
Sakthivel Velumani committed
604
  Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers);
Sakthi's avatar
Sakthi committed
605

Sakthivel Velumani's avatar
Sakthivel Velumani committed
606 607 608
  p_decParams->Z = harq_process->Z;


609 610 611 612 613
  p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
  p_decParams->outMode= 0;

  r_offset = 0;

614
  uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS;  //number of segments to be allocated
615

Francesco Mani's avatar
Francesco Mani committed
616 617
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
618
    a_segments = a_segments/273 +1;
619
  }
620

621 622
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
623
    return 1;
624 625 626 627
  }
#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
628 629 630
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
  offset = 0;
631
  void (*nr_processULSegment_ptr)(void*) = &nr_processULSegment;
632 633

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

635
    E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
636

Sakthi's avatar
Sakthi committed
637
    union ldpcReqUnion id = {.s={ulsch->rnti,frame,nr_tti_rx,0,0}};
638
    notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, phy_vars_gNB->respDecode, nr_processULSegment_ptr);
639 640 641 642
    ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);

    rdata->gNB = phy_vars_gNB;
    rdata->ulsch_harq = harq_process;
643
    rdata->decoderParms = decParams;
644
    rdata->ulsch_llr = ulsch_llr;
Sakthi's avatar
Sakthi committed
645
    rdata->Kc = kc;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
646
    rdata->harq_pid = harq_pid;
647 648 649 650 651 652
    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
653
    rdata->Kr_bytes = Kr_bytes;
654 655
    rdata->rv_index = pusch_pdu->pusch_data.rv_index;
    rdata->Tbslbrm = Tbslbrm;
Sakthi's avatar
Sakthi committed
656 657
    rdata->offset = offset;
    rdata->ulsch = ulsch;
658
    rdata->ulsch_id = ULSCH_id;
Sakthi's avatar
Sakthi committed
659 660 661
    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);
662
    r_offset += E;
Sakthi's avatar
Sakthi committed
663
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
664 665
    //////////////////////////////////////////////////////////////////////////////////////////
  }
666
  return 1;
667
}