nr_polar_decoding_tools.c 12.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 */

Guy De Souza's avatar
Guy De Souza committed
22
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
23
//#define SHOWCOMP 1
Guy De Souza's avatar
Guy De Souza committed
24

25
inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, 
26
		       uint16_t offset, uint8_t approximation) __attribute__((always_inline));
27
inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, 
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
		       uint16_t offset, uint8_t approximation) {

        double a;
        double b;
	double absA,absB;


	a = llr[col + 1][row];   
	b = llr[col+1][row + offset];
	
	if (approximation) { //eq. (9)
	  absA = fabs(a);
	  absB = fabs(b);
	  llr[col][row] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
	} else { //eq. (8a)
	  llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
	}
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
	//	printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}

inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col, 
		       uint16_t offset) __attribute__((always_inline));
inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col, 
		       uint16_t offset) {

        int16_t a;
        int16_t b;
	int16_t absA,absB;
	int16_t maska,maskb;
	int16_t minabs;

#ifdef SHOWCOMP
60
	printf("computeLLR_int8(llr,%d,%d,%d);\n",row,col,offset);
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#endif
	a = llr[col + 1][row];   
	b = llr[col+1][row + offset];
	//	printf("LLR: a %d, b %d\n",a,b);
	maska = a>>15;
	maskb = b>>15;
	absA = (a+maska)^maska;
	absB = (b+maskb)^maskb;
	//	printf("LLR: absA %d, absB %d\n",absA,absB);
	minabs = absA<absB ? absA : absB;
	if ((maska^maskb) == 0)
	  llr[col][row] = minabs;
	else 
	  llr[col][row] = -minabs;
	//	printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]);
76 77 78 79
}


void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
80 81 82
	       uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) {
  uint16_t offset = (xlen/(1<<(ylen-col-1)));
  if (( (row) % (2*offset) ) >= offset ) {
83 84 85
    if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen);
    if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
    if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
86
    for (uint8_t i=0; i<listSize; i++) {
87
      dlist[i]->llr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row];
88 89
    }
  } else {
90 91 92
    if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
    if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
    for (int i=0;i<listSize;i++) computeLLR(dlist[i]->llr, row, col, offset, approximation);
93 94 95 96 97
  }
  
  llrU[row][col]=1;
}

98 99 100
#define updateLLR_int8_A(dlist,i,col,row,offset) if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] =  dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)];


101 102 103 104 105 106 107
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
		    uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen) {
  uint16_t offset = (xlen/(1<<(ylen-col-1)));
  if (( (row) % (2*offset) ) >= offset ) {
    if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen);
    if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen);
    if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen);
108 109

      
110 111
    for (uint8_t i=0; i<listSize; i++) {
#ifdef SHOWCOMP
112
      printf("updateLLR_int8_A(dlist,%d,%d,%d,%d);\n",i,row,col,offset);
113
#endif
114 115
      updateLLR_int8_A(dlist,i,col,row,offset);
      /*
116 117 118
      if (dlist[i]->bit[col][row-offset]==0) 
	dlist[i]->llr[col][row] =  dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];
      else
119 120
	dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];*/
      }
121 122 123 124
  } else {
    if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen);
    if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen);
    for (int i=0;i<listSize;i++) computeLLR_int8(dlist[i]->llr, row, col, offset);
125
  }
126
  
127
  llrU[row][col]=1;
Guy De Souza's avatar
Guy De Souza committed
128 129
}

130 131 132 133 134 135 136 137 138 139 140 141
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
	       uint16_t col, uint16_t xlen, uint8_t ylen) {
  uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
  
  for (uint8_t i=0; i<listSize; i++) {
    if (( (row) % (2*offset) ) >= offset ) {
      if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
      dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
    } else {
      if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
      if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
      dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2);
142 143 144 145 146 147
    }
  }
  
  bitU[row][col]=1;
}

148 149 150
#define updateBit_int8_A(dlist,i,col,row) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]
#define updateBit_int8_B(dlist,i,col,row,offset) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)]

151 152 153 154 155 156 157
void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
		    uint16_t col, uint16_t xlen, uint8_t ylen) {
  uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
  
  for (uint8_t i=0; i<listSize; i++) {
    if (( (row) % (2*offset) ) >= offset ) {
      if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen);
158
      //      dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
159
#ifdef SHOWCOMP
160
      printf("updateBit_int8_A(dlist,%d,%d,%d);\n",i,col,row);
161
#endif
162 163
      updateBit_int8_A(dlist,i,col,row);

164 165 166
    } else {
      if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen);
      if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
167
      //      dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset];
168
      //      printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]);
169
#ifdef SHOWCOMP
170
      printf("updateBit_int8_B(dlist,%d,%d,%d,%d);\n",i,col,row,offset);
171
#endif
172
      updateBit_int8_B(dlist,i,col,row,offset);
173 174 175 176
    }
  }
  
  bitU[row][col]=1;
Guy De Souza's avatar
Guy De Souza committed
177
}
178
 
179
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
180 181 182 183 184 185 186 187 188
		       uint16_t row, uint8_t approximation) {
   
  if (approximation) { //eq. (12)
    for (uint8_t i=0; i<listSize; i++) {
      if ((2*bitValue) != ( 1 - copysign(1.0,dlist[i]->llr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]);
     }
  } else { //eq. (11b)
    int8_t multiplier = (2*bitValue) - 1;
    for (uint8_t i=0; i<listSize; i++) {
189 190
      dlist[i]->pathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ;
    }  
191 192
  }
  
Guy De Souza's avatar
Guy De Souza committed
193
}
194 195
 
#define updatePathMetric0_int8_A(dlist,i,row,mask,absllr) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}
Guy De Souza's avatar
Guy De Souza committed
196

197
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row) {
Guy De Souza's avatar
Guy De Souza committed
198

199 200 201 202
  int16_t mask,absllr;
  for (uint8_t i=0; i<listSize; i++) {

    updatePathMetric0_int8_A(dlist,i,row,mask,absllr);
203
#ifdef SHOWCOMP
204
    printf("updatePathMetric0_int8_A(dlist,i,%d,%d);\n",listSize,row);
205
#endif
Guy De Souza's avatar
Guy De Souza committed
206

207 208

    /*
209 210 211 212 213
      mask = dlist[i]->llr[0][row]>>15;
      
      if (mask != 0) {
        int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask; 
        dlist[i]->pathMetric += absllr;
214 215 216 217
	}*/


  }
Guy De Souza's avatar
Guy De Souza committed
218 219

}
220

221
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) {
222 223 224

  int i;

225 226 227
  for (i=0;i<listSize;i++) dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
  decoder_list_t **dlist2 = &dlist[listSize];

228 229 230
  if (appr) { //eq. (12)
    for (i = 0; i < listSize; i++) {
      // bitValue=0
231
      if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric  -= dlist[i]->llr[0][row];
232
       // bitValue=1
233
      else                         dlist2[i]->pathMetric += dlist[i]->llr[0][row];
234 235 236 237
    }
  } else { //eq. (11b)
    for (i = 0; i < listSize; i++) {
      // bitValue=0
238
       dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row]));
239
      // bitValue=1
240
       dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row]));
241

242 243 244
    }
  }
}
Guy De Souza's avatar
Guy De Souza committed
245

246 247 248
#define updatePathMetric2_int8_A(dlist,i,listSize,row)     {dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}


249 250 251 252 253
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row) {

  int i;


254
  for (i = 0; i < listSize; i++) {
255
#ifdef SHOWCOMP
256 257
    printf("updatePathMetric2_int8_A(dlist,%d,%d,%d);\n",
	   i,listSize,row);
258
#endif  
259 260 261 262
    updatePathMetric2_int8_A(dlist,i,listSize,row);
    //    dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
    //if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric  -= dlist[i]->llr[0][row];
    //else                         dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];
263 264
  }
}
265

Guy De Souza's avatar
Guy De Souza committed
266

267 268 269 270 271 272 273
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
		       uint8_t listSize, uint32_t i2, uint8_t len) {
  for (uint8_t i = 0; i < listSize; i++) {
    for (uint8_t j = 0; j < len; j++) {
      dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
    }
  }
Guy De Souza's avatar
Guy De Souza committed
274 275
}

276 277 278 279 280 281 282
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
			uint8_t listSize, uint32_t i2, uint8_t len) {
  for (uint8_t i = 0; i < listSize; i++) {
    for (uint8_t j = 0; j < len; j++) {
      dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
    }
  }
Guy De Souza's avatar
Guy De Souza committed
283
}
284

285 286
#define updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}
    
287 288 289
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
		       uint8_t listSize, uint32_t i2, uint8_t len) {
  for (uint8_t i = 0; i < listSize; i++) {
290 291 292 293 294 295 296
#ifdef SHOWCOMP
    printf("updateCrcChecksum_int8_A(dlist,%d,crcGen,%d,%d);\n",i,i2,len);
#endif
    updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len);
    //    for (uint8_t j = 0; j < len; j++) {
    //      dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
    //    }
297 298 299
  }
}

300 301
#define updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}

302 303 304
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
			uint8_t listSize, uint32_t i2, uint8_t len) {
  for (uint8_t i = 0; i < listSize; i++) {
305 306 307 308 309 310 311
#ifdef SHOWCOMP
    printf("updateCrcChecksum2_int8_A(dlist,%d,%d,crcGen,%d,%d);\n",i,listSize,i2,len);
#endif
    updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len);
    //    for (uint8_t j = 0; j < len; j++) {
    //      dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
    //    }
312 313
  }
}