nr_rate_matching.c 4.56 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 40 41 42 43 44 45 46 47 48 49 50
/*
 * 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.1  (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: nr_rate_matching.c
   purpose: Procedures for rate matching/interleaving for NR LDPC
   author: hongzhi.wang@tcl.com
*/

#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h"

//#define RM_DEBUG 1

uint8_t index_k0[2][4] = {{0,17,33,56},{0,13,25,43}};


void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
{
  uint32_t EQm;

  EQm = E/Qm;
  memset(f,0,E*sizeof(uint8_t));

  for (int j = 0; j< EQm; j++){
	  for (int i = 0; i< Qm; i++){
		  f[(i+j*Qm)] = e[(i*EQm + j)];
	  }
  }

}


Hongzhi Wang's avatar
Hongzhi Wang committed
51
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
52 53 54 55 56 57 58 59 60 61 62 63 64 65
{

  uint32_t EQm;

  EQm = E/Qm;

  for (int j = 0; j< EQm; j++){
	  for (int i = 0; i< Qm; i++){
		  e[(i*EQm + j)] = f[(i+j*Qm)];
	  }
  }
}


66 67 68 69 70 71 72 73 74
int nr_rate_matching_ldpc(uint8_t Ilbrm,
                          uint32_t Tbslbrm,
                          uint8_t BG,
                          uint16_t Z,
                          uint8_t *w,
                          uint8_t *e,
                          uint8_t C,
                          uint8_t rvidx,
                          uint32_t E)
75
{
76
  uint32_t Ncb,ind,k,Nref,N;
77

78 79 80 81
  if (C==0) {
    printf("nr_rate_matching: invalid parameters (C %d\n",C);
    return -1;
  }
82 83 84 85 86

  //Bit selection
  N = (BG==1)?(66*Z):(50*Z);

  if (Ilbrm == 0)
87
      Ncb = N;
88 89 90 91 92 93 94 95
  else {
      Nref = 3*Tbslbrm/(2*C); //R_LBRM = 2/3
      Ncb = min(N, Nref);
  }

  ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;

#ifdef RM_DEBUG
96
  printf("nr_rate_matching_ldpc: E %d, k0 %d, Ncb %d, rvidx %d\n", E, ind, Ncb, rvidx);
97 98 99 100 101 102 103 104 105 106
#endif

  k=0;

  for (; (ind<Ncb)&&(k<E); ind++) {

#ifdef RM_DEBUG
    printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
#endif

107
    if (w[ind] != NR_NULL) e[k++]=w[ind];
108 109 110 111 112 113 114 115 116
  }

  while(k<E) {
    for (ind=0; (ind<Ncb)&&(k<E); ind++) {

#ifdef RM_DEBUG
      printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
#endif

117
      if (w[ind] != NR_NULL) e[k++]=w[ind];
118 119 120 121
    }
  }


122
  return 0;
123 124 125
}

int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
126 127 128
                             uint32_t Tbslbrm,
                             uint8_t BG,
                             uint16_t Z,
129 130 131 132 133
                             int16_t *w,
                             int16_t *soft_input,
                             uint8_t C,
                             uint8_t rvidx,
                             uint8_t clear,
134
                             uint32_t E)
135
{
136
  uint32_t Ncb,ind,k,Nref,N;
137 138 139 140 141

#ifdef RM_DEBUG
  int nulled=0;
#endif

142 143 144
  if (C==0) {
    printf("nr_rate_matching: invalid parameters (C %d\n",C);
    return -1;
145 146 147 148 149 150
  }

  //Bit selection
  N = (BG==1)?(66*Z):(50*Z);

  if (Ilbrm == 0)
151
      Ncb = N;
152 153 154 155 156 157 158 159
  else {
      Nref = (3*Tbslbrm/(2*C)); //R_LBRM = 2/3
      Ncb = min(N, Nref);
  }

  ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;

#ifdef RM_DEBUG
160
  printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx);
161 162 163 164 165 166 167 168
#endif

  if (clear==1)
    memset(w,0,Ncb*sizeof(int16_t));

  k=0;

  for (; (ind<Ncb)&&(k<E); ind++) {
169 170
    if (soft_input[ind] != NR_NULL) {
      w[ind] += soft_input[k++];
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
#ifdef RM_DEBUG
      printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]);
#endif
    }

#ifdef RM_DEBUG
    else {
      printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
      nulled++;
    }

#endif
  }

  while(k<E) {
    for (ind=0; (ind<Ncb)&&(k<E); ind++) {
187 188
      if (soft_input[ind] != NR_NULL) {
        w[ind] += soft_input[k++];
189
#ifdef RM_DEBUG
190
        printf("RM_RX k%d Ind: %d (%d)(soft in %d)\n",k-1,ind,w[ind],soft_input[k-1]);
191 192 193 194 195 196 197 198 199 200 201 202 203
#endif
      }

#ifdef RM_DEBUG
      else {
        printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
        nulled++;
      }

#endif
    }
  }

204
  return 0;
205
}