nr_polar_encoder.c 12.7 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 24 25 26 27 28 29 30 31 32
/*!\file PHY/CODING/nrPolar_tools/nr_polar_encoder.c
 * \brief
 * \author Turker Yilmaz
 * \date 2018
 * \version 0.1
 * \company EURECOM
 * \email turker.yilmaz@eurecom.fr
 * \note
 * \warning
*/

yilmazt's avatar
yilmazt 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 38
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"

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

42 43 44
void polar_encoder(uint32_t *in,
				   uint32_t *out,
				   t_nrPolar_paramsPtr polarParams)
45
{
yilmazt's avatar
yilmazt committed
46 47 48 49 50 51 52 53 54 55 56
	if (polarParams->idx == 0){//PBCH
		nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
		/*
		 * Bytewise operations
		 */
		//Calculate CRC.
		nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A,
													   polarParams->crc_generator_matrix,
													   polarParams->nr_polar_crc,
													   polarParams->payloadBits,
													   polarParams->crcParityBits);
57
		for (uint8_t i = 0; i < polarParams->crcParityBits; i++) 
yilmazt's avatar
yilmazt committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
			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)];
	} else { //UCI

	}

	//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)
	nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
												   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)
yilmazt's avatar
yilmazt committed
95 96 97 98
	nr_polar_interleaver(polarParams->nr_polar_D,
						 polarParams->nr_polar_E,
						 polarParams->rate_matching_pattern,
						 polarParams->encoderLength);
Guy De Souza's avatar
Guy De Souza committed
99 100

	/*
yilmazt's avatar
yilmazt committed
101
	 * Return bits.
Guy De Souza's avatar
Guy De Souza committed
102
	 */
yilmazt's avatar
yilmazt committed
103 104 105 106
#ifdef DEBUG_POLAR_ENCODER
	for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#endif

yilmazt's avatar
yilmazt committed
107 108 109 110 111 112
	nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
}

void polar_encoder_dci(uint32_t *in,
					   uint32_t *out,
					   t_nrPolar_paramsPtr polarParams,
yilmazt's avatar
yilmazt committed
113 114 115 116 117
					   uint16_t n_RNTI)
{
#ifdef DEBUG_POLAR_ENCODER_DCI
	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]);
#endif
118 119 120 121

	/*
	 * Bytewise operations
	 */
yilmazt's avatar
yilmazt committed
122
	//(a to a')
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
	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];
#ifdef DEBUG_POLAR_ENCODER_DCI
	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");
#endif
	//Calculate CRC.
	nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_APrime,
												   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);
#ifdef DEBUG_POLAR_ENCODER_DCI
	printf("[polar_encoder_dci] CRC: ");
	for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
	printf("\n");
#endif

	//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
162 163
	nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
	//Parity bits computation (p)
164
	polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
yilmazt's avatar
yilmazt committed
165 166
#ifdef DEBUG_POLAR_ENCODER_DCI
	printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
167 168 169 170
	for (int i=0; i<32; i++)
	{
		printf("%d\n",((polarParams->crcBit)>>i)&1);
	}
yilmazt's avatar
yilmazt committed
171 172
#endif
	//(a to b)
173 174 175
	//
	// Bytewise operations
	//
yilmazt's avatar
yilmazt committed
176 177 178 179
	uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
	for (int i=0; i<arrayInd-1; i++){
		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
180 181
		}
	}
yilmazt's avatar
yilmazt committed
182 183
	for (int i=0; i<((polarParams->payloadBits)%8); i++) {
			polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
yilmazt's avatar
yilmazt committed
184 185 186 187
	}
	for (int i=0; i<8; i++) {
		polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
	}
yilmazt's avatar
yilmazt committed
188
	//Scrambling (b to c)
yilmazt's avatar
yilmazt committed
189 190 191
	for (int i=0; i<16; i++) {
		polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
				( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
192
	}*/
yilmazt's avatar
yilmazt committed
193 194 195 196 197
#ifdef DEBUG_POLAR_ENCODER_DCI
	printf("[polar_encoder_dci] B: ");
	for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
	printf("\n");
#endif
Guy De Souza's avatar
Guy De Souza committed
198 199

	//Interleaving (c to c')
yilmazt's avatar
yilmazt committed
200 201
	nr_polar_interleaver(polarParams->nr_polar_B,
						 polarParams->nr_polar_CPrime,
202 203
						 polarParams->interleaving_pattern,
						 polarParams->K);
Guy De Souza's avatar
Guy De Souza committed
204 205

	//Bit insertion (c' to u)
yilmazt's avatar
yilmazt committed
206 207
	nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
						   polarParams->nr_polar_U,
208 209 210 211 212
						   polarParams->N,
						   polarParams->K,
						   polarParams->Q_I_N,
						   polarParams->Q_PC_N,
						   polarParams->n_pc);
Guy De Souza's avatar
Guy De Souza committed
213 214

	//Encoding (u to d)
yilmazt's avatar
yilmazt committed
215
	nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
216
												   polarParams->G_N,
yilmazt's avatar
yilmazt committed
217
												   polarParams->nr_polar_D,
218 219 220
												   polarParams->N,
												   polarParams->N);
	for (uint16_t i = 0; i < polarParams->N; i++)
yilmazt's avatar
yilmazt committed
221
		polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
Guy De Souza's avatar
Guy De Souza committed
222 223 224

	//Rate matching
	//Sub-block interleaving (d to y) and Bit selection (y to e)
yilmazt's avatar
yilmazt committed
225 226 227 228
	nr_polar_interleaver(polarParams->nr_polar_D,
						 polarParams->nr_polar_E,
						 polarParams->rate_matching_pattern,
						 polarParams->encoderLength);
229 230 231 232

	/*
	 * Return bits.
	 */
yilmazt's avatar
yilmazt committed
233
	nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
yilmazt's avatar
yilmazt committed
234
#ifdef DEBUG_POLAR_ENCODER_DCI
yilmazt's avatar
yilmazt committed
235 236
	printf("[polar_encoder_dci] E: ");
	for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
yilmazt's avatar
yilmazt committed
237
	uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
yilmazt's avatar
yilmazt committed
238
	printf("\n[polar_encoder_dci] out: ");
yilmazt's avatar
yilmazt committed
239 240 241 242
	for (int i = 0; i < outputInd; i++) {
		printf("[%d]->0x%08x\t", i, out[i]);
	}
#endif
Guy De Souza's avatar
Guy De Souza committed
243
}
yilmazt's avatar
yilmazt committed
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 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

void polar_encoder_timing(uint32_t *in,
						  uint32_t *out,
						  t_nrPolar_paramsPtr polarParams,
						  double cpuFreqGHz,
						  FILE* logFile)
{
	//Initiate timing.
	time_stats_t timeEncoderCRCByte, timeEncoderCRCBit, timeEncoderInterleaver, timeEncoderBitInsertion, timeEncoder1, timeEncoder2, timeEncoderRateMatching, timeEncoderByte2Bit;
	reset_meas(&timeEncoderCRCByte); reset_meas(&timeEncoderCRCBit); reset_meas(&timeEncoderInterleaver); reset_meas(&timeEncoderBitInsertion); reset_meas(&timeEncoder1); reset_meas(&timeEncoder2); reset_meas(&timeEncoderRateMatching); reset_meas(&timeEncoderByte2Bit);
	uint16_t n_RNTI=0x0000;

	start_meas(&timeEncoderCRCByte);
	nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime); //(a to a')
	polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits)); //Parity bits computation (p)
	uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0); //(a to b)
	for (int i=0; i<arrayInd-1; i++)
		for (int j=0; j<8; j++)
			polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
	for (int i=0; i<((polarParams->payloadBits)%8); i++) polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
	for (int i=0; i<8; i++) polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
	for (int i=0; i<16; i++) polarParams->nr_polar_B[polarParams->payloadBits+8+i] =	( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2; //Scrambling (b to c)
	stop_meas(&timeEncoderCRCByte);


	start_meas(&timeEncoderCRCBit);
	nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
	nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A, polarParams->crc_generator_matrix, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits); //Calculate CRC.
	for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
	for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i]; //Attach CRC to the Transport Block. (a to b)
	for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
	stop_meas(&timeEncoderCRCBit);


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


	start_meas(&timeEncoderBitInsertion); //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);
	stop_meas(&timeEncoderBitInsertion);


	start_meas(&timeEncoder1); //Encoding (u to d)
	nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U, polarParams->G_N, polarParams->nr_polar_D, polarParams->N, polarParams->N);
	stop_meas(&timeEncoder1);


	start_meas(&timeEncoder2);
	for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
	stop_meas(&timeEncoder2);


	start_meas(&timeEncoderRateMatching);//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);
	stop_meas(&timeEncoderRateMatching);


	start_meas(&timeEncoderByte2Bit); //Return bits.
	nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
	stop_meas(&timeEncoderByte2Bit);

	fprintf(logFile,",%f,%f,%f,%f,%f,%f,%f,%f\n",
			(timeEncoderCRCByte.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoderCRCBit.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoderInterleaver.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoderBitInsertion.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoder1.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoder2.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoderRateMatching.diff_now/(cpuFreqGHz*1000.0)),
			(timeEncoderByte2Bit.diff_now/(cpuFreqGHz*1000.0)));
}