nr_polar_encoder.c 20.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
/*
 * 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
 */

22 23
/*!\file PHY/CODING/nrPolar_tools/nr_polar_encoder.c
 * \brief
yilmazt's avatar
yilmazt committed
24
 * \author Raymond Knopp, Turker Yilmaz
25 26 27
 * \date 2018
 * \version 0.1
 * \company EURECOM
yilmazt's avatar
yilmazt committed
28
 * \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr
29 30
 * \note
 * \warning
31
 */
32

knopp's avatar
knopp committed
33
//#define DEBUG_POLAR_ENCODER
Guy De Souza's avatar
Guy De Souza committed
34
//#define DEBUG_POLAR_ENCODER_DCI
yilmazt's avatar
yilmazt committed
35
//#define DEBUG_POLAR_ENCODER_TIMING
yilmazt's avatar
yilmazt committed
36

Guy De Souza's avatar
Guy De Souza committed
37
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
38
#include "assertions.h"
Guy De Souza's avatar
Guy De Souza committed
39

yilmazt's avatar
yilmazt committed
40 41 42
//input  [a_31 a_30 ... a_0]
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...

43
void polar_encoder(uint32_t *in,
44 45
		   uint32_t *out,
		   t_nrPolar_paramsPtr polarParams)
46
{
47
  if (polarParams->idx == 0){//PBCH
48
    /*
49 50 51 52
    uint64_t B = (((uint64_t)*in)&((((uint64_t)1)<<32)-1)) | (((uint64_t)crc24c((uint8_t*)in,polarParams->payloadBits)>>8)<<polarParams->payloadBits);
#ifdef DEBUG_POLAR_ENCODER
    printf("polar_B %llx (crc %x)\n",B,crc24c((uint8_t*)in,polarParams->payloadBits)>>8);
#endif
53 54 55
nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/

    nr_bit2byte_uint32_8_t((uint32_t*)in, polarParams->payloadBits, polarParams->nr_polar_A);
56 57 58 59
    /*
     * Bytewise operations
     */
    //Calculate CRC.
60
    
yilmazt's avatar
yilmazt committed
61
      nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
						     polarParams->crc_generator_matrix,
						     polarParams->nr_polar_crc,
						     polarParams->payloadBits,
						     polarParams->crcParityBits);
      for (uint8_t i = 0; i < polarParams->crcParityBits; i++) 
	polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
      
      
      //Attach CRC to the Transport Block. (a to b)
      for (uint16_t i = 0; i < polarParams->payloadBits; i++)
	polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
      for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
	polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
    
#ifdef DEBUG_POLAR_ENCODER
77 78 79
    uint64_t B2=0;
    for (int i = 0;i<polarParams->K;i++) B2 = B2 | ((uint64_t)polarParams->nr_polar_B[i] << i);
    printf("polar_B %llx\n",B2);
80
#endif
81 82 83 84 85 86
    /*    for (int j=0;j<polarParams->crcParityBits;j++) {
      for (int i=0;i<polarParams->payloadBits;i++) 
	printf("%1d.%1d+",polarParams->crc_generator_matrix[i][j],polarParams->nr_polar_A[i]);
      printf(" => %d\n",polarParams->nr_polar_crc[j]);
      }*/
	  
87 88 89 90 91 92 93 94 95 96
  } else { //UCI

  }

  //Interleaving (c to c')
  nr_polar_interleaver(polarParams->nr_polar_B,
		       polarParams->nr_polar_CPrime,
		       polarParams->interleaving_pattern,
		       polarParams->K);

97 98

#ifdef DEBUG_POLAR_ENCODER    
99 100 101 102 103 104 105
  uint64_t Cprime=0;
  for (int i = 0;i<polarParams->K;i++) {
    Cprime = Cprime | ((uint64_t)polarParams->nr_polar_CPrime[i] << i);
    if (polarParams->nr_polar_CPrime[i] == 1) printf("pos %d : %llx\n",i,Cprime);
  }
  printf("polar_Cprime %llx\n",Cprime);
#endif  
106 107 108 109 110 111 112 113 114 115
  //Bit insertion (c' to u)
  nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
			 polarParams->nr_polar_U,
			 polarParams->N,
			 polarParams->K,
			 polarParams->Q_I_N,
			 polarParams->Q_PC_N,
			 polarParams->n_pc);

  //Encoding (u to d)
116 117 118
  /*  memset(polarParams->nr_polar_U,0,polarParams->N);
  polarParams->nr_polar_U[247]=1;
  polarParams->nr_polar_U[253]=1;*/
yilmazt's avatar
yilmazt committed
119
  nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
120 121 122 123 124 125 126
						 polarParams->G_N,
						 polarParams->nr_polar_D,
						 polarParams->N,
						 polarParams->N);
  for (uint16_t i = 0; i < polarParams->N; i++)
    polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);

127 128 129 130 131 132 133 134
  uint64_t D[8];
  memset((void*)D,0,8*sizeof(int64_t));
#ifdef DEBUG_POLAR_ENCODER
  for (int i=0;i<polarParams->N;i++)  D[i/64] |= ((uint64_t)polarParams->nr_polar_D[i])<<(i&63);
  printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
	 D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
#endif

135 136 137 138 139 140 141 142 143 144
  //Rate matching
  //Sub-block interleaving (d to y) and Bit selection (y to e)
  nr_polar_interleaver(polarParams->nr_polar_D,
		       polarParams->nr_polar_E,
		       polarParams->rate_matching_pattern,
		       polarParams->encoderLength);

  /*
   * Return bits.
   */
yilmazt's avatar
yilmazt committed
145
#ifdef DEBUG_POLAR_ENCODER
146
  for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
yilmazt's avatar
yilmazt committed
147 148
#endif

149
  nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
yilmazt's avatar
yilmazt committed
150 151 152
}

void polar_encoder_dci(uint32_t *in,
153 154 155
		       uint32_t *out,
		       t_nrPolar_paramsPtr polarParams,
		       uint16_t n_RNTI)
yilmazt's avatar
yilmazt committed
156 157
{
#ifdef DEBUG_POLAR_ENCODER_DCI
158
  printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
yilmazt's avatar
yilmazt committed
159
#endif
160

161 162 163 164 165 166 167
  /*
   * Bytewise operations
   */
  //(a to a')
  nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
  for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
  for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
168
#ifdef DEBUG_POLAR_ENCODER_DCI
169 170 171 172 173 174 175 176 177
  printf("[polar_encoder_dci] A: ");
  for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
  printf("\n");
  printf("[polar_encoder_dci] APrime: ");
  for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
  printf("\n");
  printf("[polar_encoder_dci] GP: ");
  for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
  printf("\n");
178
#endif
179
  //Calculate CRC.
yilmazt's avatar
yilmazt committed
180
  nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_APrime,
181 182 183 184 185
						 polarParams->crc_generator_matrix,
						 polarParams->nr_polar_crc,
						 polarParams->K,
						 polarParams->crcParityBits);
  for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
186
#ifdef DEBUG_POLAR_ENCODER_DCI
187 188 189
  printf("[polar_encoder_dci] CRC: ");
  for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
  printf("\n");
190 191
#endif

192 193 194 195 196 197 198 199 200 201 202 203
  //Attach CRC to the Transport Block. (a to b)
  for (uint16_t i = 0; i < polarParams->payloadBits; i++)
    polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
  for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
    polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
  //Scrambling (b to c)
  for (int i=0; i<16; i++) {
    polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
      ( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
  }

  /*	//(a to a')
yilmazt's avatar
yilmazt committed
204 205
	nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
	//Parity bits computation (p)
206
	polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
207
	#ifdef DEBUG_POLAR_ENCODER_DCI
yilmazt's avatar
yilmazt committed
208
	printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
209 210
	for (int i=0; i<32; i++)
	{
211
	printf("%d\n",((polarParams->crcBit)>>i)&1);
212
	}
213
	#endif
yilmazt's avatar
yilmazt committed
214
	//(a to b)
215 216 217
	//
	// Bytewise operations
	//
yilmazt's avatar
yilmazt committed
218 219
	uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
	for (int i=0; i<arrayInd-1; i++){
220 221 222
	for (int j=0; j<8; j++) {
	polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
	}
yilmazt's avatar
yilmazt committed
223
	}
yilmazt's avatar
yilmazt committed
224
	for (int i=0; i<((polarParams->payloadBits)%8); i++) {
225
	polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
yilmazt's avatar
yilmazt committed
226 227
	}
	for (int i=0; i<8; i++) {
228
	polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
yilmazt's avatar
yilmazt committed
229
	}
yilmazt's avatar
yilmazt committed
230
	//Scrambling (b to c)
yilmazt's avatar
yilmazt committed
231
	for (int i=0; i<16; i++) {
232 233
	polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
	( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
234
	}*/
yilmazt's avatar
yilmazt committed
235
#ifdef DEBUG_POLAR_ENCODER_DCI
236 237 238
  printf("[polar_encoder_dci] B: ");
  for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
  printf("\n");
yilmazt's avatar
yilmazt committed
239
#endif
Guy De Souza's avatar
Guy De Souza committed
240

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
  //Interleaving (c to c')
  nr_polar_interleaver(polarParams->nr_polar_B,
		       polarParams->nr_polar_CPrime,
		       polarParams->interleaving_pattern,
		       polarParams->K);

  //Bit insertion (c' to u)
  nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
			 polarParams->nr_polar_U,
			 polarParams->N,
			 polarParams->K,
			 polarParams->Q_I_N,
			 polarParams->Q_PC_N,
			 polarParams->n_pc);

  //Encoding (u to d)
yilmazt's avatar
yilmazt committed
257
  nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
						 polarParams->G_N,
						 polarParams->nr_polar_D,
						 polarParams->N,
						 polarParams->N);
  for (uint16_t i = 0; i < polarParams->N; i++)
    polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);

  //Rate matching
  //Sub-block interleaving (d to y) and Bit selection (y to e)
  nr_polar_interleaver(polarParams->nr_polar_D,
		       polarParams->nr_polar_E,
		       polarParams->rate_matching_pattern,
		       polarParams->encoderLength);

  /*
   * Return bits.
   */
  nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
yilmazt's avatar
yilmazt committed
276
#ifdef DEBUG_POLAR_ENCODER_DCI
277 278 279 280 281 282 283
  printf("[polar_encoder_dci] E: ");
  for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
  uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
  printf("\n[polar_encoder_dci] out: ");
  for (int i = 0; i < outputInd; i++) {
    printf("[%d]->0x%08x\t", i, out[i]);
  }
yilmazt's avatar
yilmazt committed
284
#endif
Guy De Souza's avatar
Guy De Souza committed
285
}
yilmazt's avatar
yilmazt committed
286

287 288 289 290 291 292 293
static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,void *out) __attribute__((always_inline));

static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,void *out) {

  if (polarParams->groupsize == 8) 
    for (int i=0;i<polarParams->encoderLength>>3;i++) ((uint8_t*)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
  else
294 295 296
    for (int i=0;i<polarParams->encoderLength>>4;i++) {
      ((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
    }
297
}
298 299 300 301 302 303

void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
  
  // build table b -> c'

  AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
304
  AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K);
305
  
306
  int bit_i,ip;
307

308 309 310 311 312 313 314
  int numbytes = polarParams->K>>3;
  int residue = polarParams->K&7;
  int numbits;
  if (residue>0) numbytes++;
  for (int byte=0;byte<numbytes;byte++) {
    if (byte<(polarParams->K>>3)) numbits=8;
    else numbits=residue;
315
    for (int val=0;val<256;val++) {
316 317
      polarParams->cprime_tab0[byte][val] = 0;
      polarParams->cprime_tab1[byte][val] = 0;
318
      for (int i=0;i<numbits;i++) {
319 320
	// flip bit endian of B bitstring
	ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)];
321
	AssertFatal(ip<128,"ip = %d\n",ip);
322
	bit_i=(val>>i)&1;
323 324
	if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<<ip);				
	else       polarParams->cprime_tab1[byte][val] |= (((uint64_t)bit_i)<<(ip&63));				
325 326 327
      }
    }
  }
328

329 330 331 332
  AssertFatal(polarParams->N==512,"N = %d, not done yet\n",polarParams->N);

  // build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
  // keep only rows of G which correspond to information/crc bits
333
  polarParams->G_N_tab = (uint64_t**)malloc(polarParams->K * sizeof(int64_t*));
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 361 362 363
  int k=0;
  for (int i=0;i<polarParams->N;i++) {
    if (polarParams->information_bit_pattern[i] > 0) {
      polarParams->G_N_tab[k] = (uint64_t*)memalign(32,(polarParams->N/64)*sizeof(uint64_t));
      memset((void*)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t));
      for (int j=0;j<polarParams->N;j++) 
	polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63);
#ifdef DEBUG_POLAR_ENCODER
      printf("Bit %d Selecting row %d of G : ",k,i);
      for (int j=0;j<polarParams->N;j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8));
      printf("\n");
#endif
      k++;
    }
  }

  // rate matching table
  int iplast=polarParams->rate_matching_pattern[0];
  int ccnt=0;
  int groupcnt=0;
  int firstingroup_out=0;
  int firstingroup_in=iplast;
  int mingroupsize = 1024;
  // compute minimum group size of rate-matching pattern
  for (int outpos=1; outpos<polarParams->encoderLength; outpos++) {
    
    ip=polarParams->rate_matching_pattern[outpos];
    if ((ip - iplast) == 1) ccnt++;
    else {
      groupcnt++;
knopp's avatar
knopp committed
364
#ifdef DEBUG_POLAR_ENCODER
365 366 367
      printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1,
	     firstingroup_in,firstingroup_in+ccnt,
	     firstingroup_out,firstingroup_out+ccnt);
knopp's avatar
knopp committed
368
#endif
369 370 371 372 373 374
      if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
      ccnt=0;
      firstingroup_out=outpos;
      firstingroup_in=ip;
    }
    iplast=ip;
375
  }
yilmazt's avatar
yilmazt committed
376
  AssertFatal(mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize);
377 378 379 380 381
  polarParams->groupsize=mingroupsize;
  int shift=3;
  if (mingroupsize == 16) shift=4;
  polarParams->rm_tab=(int*)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
  // rerun again to create groups
yilmazt's avatar
yilmazt committed
382
  int tcnt=0;
383 384 385
  for (int outpos=0;outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++) 
    polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift;
    
386
}
yilmazt's avatar
yilmazt committed
387

yilmazt's avatar
yilmazt committed
388
void polar_encoder_fast(uint64_t *A,
389
			uint32_t *out,
390
			int32_t crcmask,
391 392 393
			t_nrPolar_paramsPtr polarParams) {

  AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
394 395
  AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
  AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
396

397
  uint64_t B[4]={0,0,0,0},Cprime[4]={0,0,0,0};
398 399
  int bitlen = polarParams->payloadBits;

400 401 402
  // append crc
 
  AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
403 404
  AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");

405
  //int bitlen0=bitlen;
406

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
  uint64_t tcrc=0;

  // A bitstring should be stored as a_{N-1} a_{N-2} ... a_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A

  // First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH)
  // CRC reads in each byte in bit positions 7 downto 0, for PBCH/PDCCH we need to read in a_{A-1} downto a_{0}, A = length of bit string (e.g. 32 for PBCH)
  if (bitlen<=32) {
    uint8_t A32_flip[4];
    uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
    A32_flip[0]=((uint8_t*)&Aprime)[3];
    A32_flip[1]=((uint8_t*)&Aprime)[2];
    A32_flip[2]=((uint8_t*)&Aprime)[1];
    A32_flip[3]=((uint8_t*)&Aprime)[0];
    tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8)));
  }
  else if (bitlen<=64) {
423
    uint8_t A64_flip[8];
424 425 426 427 428 429 430 431 432 433 434 435
    uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen));
    A64_flip[0]=((uint8_t*)&Aprime)[7];
    A64_flip[1]=((uint8_t*)&Aprime)[6];
    A64_flip[2]=((uint8_t*)&Aprime)[5];
    A64_flip[3]=((uint8_t*)&Aprime)[4];
    A64_flip[4]=((uint8_t*)&Aprime)[3];
    A64_flip[5]=((uint8_t*)&Aprime)[2];
    A64_flip[6]=((uint8_t*)&Aprime)[1];
    A64_flip[7]=((uint8_t*)&Aprime)[0];
    tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8)));
  }

436
  int n;
437 438 439 440 441 442 443 444
  // this is number of quadwords in the bit string
  int quadwlen = (polarParams->K>>6);
  if ((polarParams->K&63) > 0) quadwlen++;

  // Create the B bitstring as
  // b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0

  for (n=0;n<quadwlen;n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc;
445
                           else      B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
446 447
  
    
448
  uint8_t *Bbyte = (uint8_t*)B;
449
  // for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
450
  if (polarParams->K<65) 
451 452 453 454 455 456 457 458 459
    Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
                polarParams->cprime_tab0[1][Bbyte[1]] |
                polarParams->cprime_tab0[2][Bbyte[2]] |
                polarParams->cprime_tab0[3][Bbyte[3]] |
                polarParams->cprime_tab0[4][Bbyte[4]] |
                polarParams->cprime_tab0[5][Bbyte[5]] |
                polarParams->cprime_tab0[6][Bbyte[6]] |
                polarParams->cprime_tab0[7][Bbyte[7]];
  
460 461 462 463 464
  else if (polarParams->K < 129) {
    for (int i=0;i<1+(polarParams->K/8);i++) {
      Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
      Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]];
    }
465
  }
466 467

#ifdef DEBUG_POLAR_ENCODER
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
  if (polarParams->K<65) 
    printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n",
	   (unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
	   (unsigned long long)(B[0]),
	   (unsigned long long)(Cprime[0]),
	   polarParams->payloadBits,
	   tcrc);
  else if (polarParams->K<129) {
    if (bitlen<64)
      printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
	     (unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
	     (unsigned long long)(B[1]),(unsigned long long)(B[0]),
	     (unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
	     polarParams->payloadBits,
	     tcrc);
    else 
      printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
	     (unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]),
	     (unsigned long long)(B[1]),(unsigned long long)(B[0]),
	     (unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
	     polarParams->payloadBits,
	     crc24c((uint8_t*)A,bitlen)>>8);
  }
491 492 493 494 495 496 497 498 499 500
#endif
  /*  printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]);
  printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] , 
		  polarParams->cprime_tab[1][Bbyte[1]] , 
		  polarParams->cprime_tab[2][Bbyte[2]] , 
		  polarParams->cprime_tab[3][Bbyte[3]] , 
		  polarParams->cprime_tab[4][Bbyte[4]] , 
		  polarParams->cprime_tab[5][Bbyte[5]] , 
		  polarParams->cprime_tab[6][Bbyte[6]] , 
		  polarParams->cprime_tab[7][Bbyte[7]]);*/
501 502 503 504
  
  // now do Gu product (here using 64-bit XORs, we can also do with SIMD after)
  // here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ?

505
  uint64_t Cprime_i;
506 507 508 509 510 511 512 513 514
  /*  printf("%llx Cprime_0 (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",Cprime_i,Cprime &1,
	 polarParams->G_N_tab[0][0],
	 polarParams->G_N_tab[0][1],
	 polarParams->G_N_tab[0][2],
	 polarParams->G_N_tab[0][3],
	 polarParams->G_N_tab[0][4],
	 polarParams->G_N_tab[0][5],
	 polarParams->G_N_tab[0][6],
	 polarParams->G_N_tab[0][7]);*/
515 516 517 518 519
  uint64_t D[8]={0,0,0,0,0,0,0,0};
  int off=0;
  int len=polarParams->K;
  for (int j=0;j<(1+(polarParams->K>>6));j++,off+=64,len-=64) {
    for (int i=0;i<((len>63) ? 64 : len);i++) {
520

521
      Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
522
      /*
523
#ifdef DEBUG_POLAR_ENCODER
524
      printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
525 526 527 528 529 530 531 532 533
	     Cprime_i,off+i,(Cprime[j]>>i) &1,
	     polarParams->G_N_tab[off+i][0],
	     polarParams->G_N_tab[off+i][1],
	     polarParams->G_N_tab[off+i][2],
	     polarParams->G_N_tab[off+i][3],
	     polarParams->G_N_tab[off+i][4],
	     polarParams->G_N_tab[off+i][5],
	     polarParams->G_N_tab[off+i][6],
	     polarParams->G_N_tab[off+i][7]);
534
#endif
535
      */
536 537 538 539 540 541 542 543 544
      uint64_t *Gi=polarParams->G_N_tab[off+i];
      D[0] ^= (Cprime_i & Gi[0]);
      D[1] ^= (Cprime_i & Gi[1]);
      D[2] ^= (Cprime_i & Gi[2]);
      D[3] ^= (Cprime_i & Gi[3]);
      D[4] ^= (Cprime_i & Gi[4]);
      D[5] ^= (Cprime_i & Gi[5]);
      D[6] ^= (Cprime_i & Gi[6]);
      D[7] ^= (Cprime_i & Gi[7]);
545
    }
546
  }
547 548 549 550 551 552 553 554 555 556 557
#ifdef DEBUG_POLAR_ENCODER
  printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
	 D[0],
	 D[1],
	 D[2],
	 D[3],
	 D[4],
	 D[5],
	 D[6],
	 D[7]);
#endif
558

559
  polar_rate_matching(polarParams,(void*)D,(void*)out);  
yilmazt's avatar
yilmazt committed
560 561

}