Commit 742700fa authored by Hongzhi's avatar Hongzhi

Merge branch 'nr_smallBlockCoding' into nr_pdcch

parents 11c1256f d056ae85
...@@ -1130,20 +1130,16 @@ set(PHY_POLARSRC ...@@ -1130,20 +1130,16 @@ set(PHY_POLARSRC
${OPENAIR1_DIR}/PHY/CODING/nr_polar_init.c ${OPENAIR1_DIR}/PHY/CODING/nr_polar_init.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_crc_byte.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_crc_byte.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_output_length.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_procedures.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
) )
set(PHY_TURBOIF set(PHY_TURBOIF
${OPENAIR1_DIR}/PHY/CODING/coding_load.c ${OPENAIR1_DIR}/PHY/CODING/coding_load.c
...@@ -2558,7 +2554,7 @@ target_link_libraries (dlsim_tm4 ...@@ -2558,7 +2554,7 @@ target_link_libraries (dlsim_tm4
) )
add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c) add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c)
target_link_libraries(polartest m SIMU PHY PHY_NR -lm ${ATLAS_LIBRARIES}) target_link_libraries(polartest m SIMU PHY PHY_NR PHY_COMMON -lm ${ATLAS_LIBRARIES})
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
......
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
#include <time.h> #include <time.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/coding_defs.h"
#include "SIMULATION/TOOLS/sim.h" #include "SIMULATION/TOOLS/sim.h"
//#define DEBUG_POLAR_PARAMS //#define DEBUG_POLAR_PARAMS
#define DEBUG_DCI_POLAR_PARAMS
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
...@@ -21,6 +23,8 @@ int main(int argc, char *argv[]) { ...@@ -21,6 +23,8 @@ int main(int argc, char *argv[]) {
reset_meas(&timeDecoder); reset_meas(&timeDecoder);
randominit(0); randominit(0);
crcTableInit();
uint32_t crc;
//Default simulation values (Aim for iterations = 1000000.) //Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
...@@ -30,7 +34,7 @@ int main(int argc, char *argv[]) { ...@@ -30,7 +34,7 @@ int main(int argc, char *argv[]) {
int8_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error. int8_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0; uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0;
double timeEncoderCumulative = 0, timeDecoderCumulative = 0; double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint8_t aggregation_level; uint8_t aggregation_level, decoderListSize, pathMetricAppr;
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:")) != -1) while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:")) != -1)
switch (arguments) switch (arguments)
...@@ -105,36 +109,83 @@ int main(int argc, char *argv[]) { ...@@ -105,36 +109,83 @@ int main(int argc, char *argv[]) {
} }
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n"); fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
uint8_t *testInput = malloc(sizeof(uint8_t) * testLength); //generate randomly //uint8_t *testInput = malloc(sizeof(uint8_t) * testLength); //generate randomly
uint8_t *encoderOutput = malloc(sizeof(uint8_t) * coderLength); //uint8_t *encoderOutput = malloc(sizeof(uint8_t) * coderLength);
uint32_t testInput[4], encoderOutput[4];
memset(testInput,0,sizeof(testInput));
memset(encoderOutput,0,sizeof(encoderOutput));
double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input
double *channelOutput = malloc (sizeof(double) * coderLength); //add noise double *channelOutput = malloc (sizeof(double) * coderLength); //add noise
uint8_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output uint32_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output
t_nrPolar_paramsPtr nrPolar_params = NULL; t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
#ifdef DEBUG_POLAR_PARAMS
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
nr_polar_init(&nrPolar_params, 1, 20, 1); #ifdef DEBUG_DCI_POLAR_PARAMS
nr_polar_init(&nrPolar_params, 1, 21, 1); unsigned int poly24c = 0xb2b11700;
printf("testInput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
testInput[0], testInput[1], testInput[2], testInput[3]);
printf("encOutput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
encoderOutput[0], encoderOutput[1], encoderOutput[2], encoderOutput[3]);
testInput[0]=0x01189400;
uint8_t testInput2[8];
nr_crc_bit2bit_uint32_8_t(testInput, 32, testInput2);
printf("testInput2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x \t\n",
testInput2[0], testInput2[1], testInput2[2], testInput2[3],
testInput2[4], testInput2[5], testInput2[6], testInput2[7]);
printf("crc32: [0]->0x%08x\n",crc24c(testInput2, 32));
printf("crc56: [0]->0x%08x\n",crc24c(testInput2, 56));
return 0;
uint8_t testInput8[4];
/*testInput8[0]=0x00;
testInput8[1]=0x49;
testInput8[2]=0x81;
testInput8[3]=0x10;
testInput8[4]=0x00;*/
testInput8[0]=0xff;
testInput8[1]=0xd0;
testInput8[2]=0xff;
testInput8[3]=0x82;
crc = crc24c(testInput8, 31);
for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1);
printf("crc: [0]->0x%08x\n",crc);
printf("crcbit: %x\n",crcbit(testInput8, 3, poly24c));
return 0;
unsigned char test[] = "Thebigredfox";
for (int i=0;i<8;i++) printf("[i]=%d\n",(test[0]>>i)&1);
printf("test[0]=%x\n",test[0]);
printf("%s -- sizeof=%d\n",test,sizeof(test));
printf("%x\n", crcbit(test, sizeof(test) - 1, poly24c));
printf("%x\n", crc24c(test, (sizeof(test) - 1)*8));
polarMessageType = 1;
testLength = 41;
aggregation_level=1;
coderLength = 108;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
nr_polar_print_polarParams(nrPolar_params); nr_polar_print_polarParams(nrPolar_params);
uint32_t in[4]; crc = crc24c(testInput, testLength)>>8;
in[0]=0x01189400; for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1);
in[1]=0xffffff0f; printf("crc: [0]->0x%08x\n",crc);
uint8_t *out = malloc(sizeof(uint8_t) * 41); testInput[testLength>>3] = ((uint8_t*)&crc)[2];
nr_bit2byte_uint32_8_t(in, 41, out); testInput[1+(testLength>>3)] = ((uint8_t*)&crc)[1];
for (int i=0;i<41;i++) testInput[2+(testLength>>3)] = ((uint8_t*)&crc)[0];
printf("out[%d]=%d\n",i,out[i]); printf("testInput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
uint32_t inn[4]; testInput[0], testInput[1], testInput[2], testInput[3]);
nr_byte2bit_uint8_32_t(out, 41, inn); return (0);
printf("inn[0]=%#x, inn[1]=%#x\n",inn[0],inn[1]); currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level);
polar_encoder(testInput, encoderOutput, currentPtr);
printf("AFTER POLAR ENCODING\n");
printf("testInput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
testInput[0], testInput[1], testInput[2], testInput[3]);
printf("encOutput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
encoderOutput[0], encoderOutput[1], encoderOutput[2], encoderOutput[3]);
return (0); return (0);
#endif #endif
t_nrPolar_paramsPtr currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength); currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level);
// We assume no a priori knowledge available about the payload. // We assume no a priori knowledge available about the payload.
double aPrioriArray[currentPtr->payloadBits]; double aPrioriArray[currentPtr->payloadBits];
......
...@@ -341,6 +341,14 @@ based on 3GPP UMTS/LTE specifications. ...@@ -341,6 +341,14 @@ based on 3GPP UMTS/LTE specifications.
*/ */
uint32_t crc24b (uint8_t *inPtr, int32_t bitlen); uint32_t crc24b (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc24c(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 24-bit crc ('c' variant for transport-block segments)
based on 3GPP Rel 15 specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits
*/
uint32_t crc24c (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen) /*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 16-bit crc based on 3GPP UMTS specifications. \brief This computes a 16-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream @param inPtr Pointer to input byte stream
......
...@@ -36,8 +36,12 @@ ...@@ -36,8 +36,12 @@
/*ref 36-212 v8.6.0 , pp 8-9 */ /*ref 36-212 v8.6.0 , pp 8-9 */
/* the highest degree is set by default */ /* the highest degree is set by default */
unsigned int poly24a = 0x864cfb00; //1000 0110 0100 1100 1111 1011 D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1 unsigned int poly24a = 0x864cfb00; // 1000 0110 0100 1100 1111 1011
unsigned int poly24b = 0x80006300; // 1000 0000 0000 0000 0110 0011 D^24 + D^23 + D^6 + D^5 + D + 1 // D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1
unsigned int poly24b = 0x80006300; // 1000 0000 0000 0000 0110 0011
// D^24 + D^23 + D^6 + D^5 + D + 1
unsigned int poly24c = 0xb2b11700; // 1011 0010 1011 0001 0001 0111
// D^24+D^23+D^21+D^20+D^17+D^15+D^13+D^12+D^8+D^4+D^2+D+1
unsigned int poly16 = 0x10210000; // 0001 0000 0010 0001 D^16 + D^12 + D^5 + 1 unsigned int poly16 = 0x10210000; // 0001 0000 0010 0001 D^16 + D^12 + D^5 + 1
unsigned int poly12 = 0x80F00000; // 1000 0000 1111 D^12 + D^11 + D^3 + D^2 + D + 1 unsigned int poly12 = 0x80F00000; // 1000 0000 1111 D^12 + D^11 + D^3 + D^2 + D + 1
unsigned int poly8 = 0x9B000000; // 1001 1011 D^8 + D^7 + D^4 + D^3 + D + 1 unsigned int poly8 = 0x9B000000; // 1001 1011 D^8 + D^7 + D^4 + D^3 + D + 1
...@@ -49,8 +53,9 @@ For initialization && verification purposes, ...@@ -49,8 +53,9 @@ For initialization && verification purposes,
The first bit is in the MSB of each byte The first bit is in the MSB of each byte
*********************************************************/ *********************************************************/
unsigned int unsigned int crcbit (unsigned char * inputptr,
crcbit (unsigned char * inputptr, int octetlen, unsigned int poly) int octetlen,
unsigned int poly)
{ {
unsigned int i, crc = 0, c; unsigned int i, crc = 0, c;
...@@ -77,6 +82,7 @@ crc table initialization ...@@ -77,6 +82,7 @@ crc table initialization
*********************************************************/ *********************************************************/
static unsigned int crc24aTable[256]; static unsigned int crc24aTable[256];
static unsigned int crc24bTable[256]; static unsigned int crc24bTable[256];
static unsigned int crc24cTable[256];
static unsigned short crc16Table[256]; static unsigned short crc16Table[256];
static unsigned short crc12Table[256]; static unsigned short crc12Table[256];
static unsigned char crc8Table[256]; static unsigned char crc8Table[256];
...@@ -88,6 +94,7 @@ void crcTableInit (void) ...@@ -88,6 +94,7 @@ void crcTableInit (void)
do { do {
crc24aTable[c] = crcbit (&c, 1, poly24a); crc24aTable[c] = crcbit (&c, 1, poly24a);
crc24bTable[c] = crcbit (&c, 1, poly24b); crc24bTable[c] = crcbit (&c, 1, poly24b);
crc24cTable[c] = crcbit (&c, 1, poly24c);
crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16); crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16);
crc12Table[c] = (unsigned short) (crcbit (&c, 1, poly12) >> 16); crc12Table[c] = (unsigned short) (crcbit (&c, 1, poly12) >> 16);
crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24); crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24);
...@@ -99,8 +106,8 @@ Byte by byte implementations, ...@@ -99,8 +106,8 @@ Byte by byte implementations,
assuming initial byte is 0 padded (in MSB) if necessary assuming initial byte is 0 padded (in MSB) if necessary
*********************************************************/ *********************************************************/
unsigned int unsigned int crc24a (unsigned char * inptr,
crc24a (unsigned char * inptr, int bitlen) int bitlen)
{ {
int octetlen, resbit; int octetlen, resbit;
...@@ -119,9 +126,9 @@ crc24a (unsigned char * inptr, int bitlen) ...@@ -119,9 +126,9 @@ crc24a (unsigned char * inptr, int bitlen)
return crc; return crc;
} }
unsigned int crc24b (unsigned char * inptr, int bitlen) unsigned int crc24b (unsigned char * inptr,
int bitlen)
{ {
int octetlen, resbit; int octetlen, resbit;
unsigned int crc = 0; unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */ octetlen = bitlen / 8; /* Change in octets */
...@@ -138,6 +145,27 @@ unsigned int crc24b (unsigned char * inptr, int bitlen) ...@@ -138,6 +145,27 @@ unsigned int crc24b (unsigned char * inptr, int bitlen)
return crc; return crc;
} }
unsigned int crc24c (unsigned char * inptr,
int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
/*#ifdef DEBUG_CRC24C
printf("crc24c: in %x => crc %x (%x)\n",crc,*inptr,crc24cTable[(*inptr) ^ (crc >> 24)]);
#endif*/
crc = (crc << 8) ^ crc24cTable[(*inptr++) ^ (crc >> 24)];
}
if (resbit > 0)
crc = (crc << resbit) ^ crc24cTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
unsigned int unsigned int
crc16 (unsigned char * inptr, int bitlen) crc16 (unsigned char * inptr, int bitlen)
{ {
......
...@@ -41,3 +41,16 @@ void nr_byte2bit_uint8_32_t(uint8_t *in, uint16_t arraySize, uint32_t *out) { ...@@ -41,3 +41,16 @@ void nr_byte2bit_uint8_32_t(uint8_t *in, uint16_t arraySize, uint32_t *out) {
out[i]|=in[(i*32)]; out[i]|=in[(i*32)];
} }
} }
void nr_crc_bit2bit_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out) {
out[0]=0xff;
out[1]=0xff;
out[2]=0xff;
uint8_t arrayInd = ceil(arraySize / 32.0);
for (int i = 0; i < arrayInd; i++) {
out[3+i*4] = ((in[i] & (0x0000000f))<<4) | ((in[i] & (0x000000f0))>>4);
out[4+i*4] = (((in[i] & (0x00000f00))<<4) | ((in[i] & (0x0000f000))>>4))>>8;
out[5+i*4] = (((in[i] & (0x000f0000))<<4) | ((in[i] & (0x00f00000))>>4))>>16;
out[6+i*4] = (((in[i] & (0x0f000000))<<4) | ((in[i] & (0xf0000000))>>4))>>24;
}
}
/*
* 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
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, uint16_t K,
int16_t *Q_I_N, int16_t *Q_PC_N, uint8_t n_PC){
uint16_t k=0;
uint8_t flag;
if (n_PC>0) {
/*
*
*/
} else {
for (int n=0; n<=N-1; n++) {
flag=0;
for (int m=0; m<=(K+n_PC)-1; m++) {
if ( n == Q_I_N[m]) {
flag=1;
break;
}
}
if (flag) { // n ϵ Q_I_N
output[n]=input[k];
k++;
} else {
output[n] = 0;
}
}
}
}
/*
* 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
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_channel_interleaver_pattern(uint16_t *cip, uint8_t I_BIL, uint16_t E){
if (I_BIL == 1) {
uint16_t T=0, k;
while( ((T/2)*(T+1)) < E ) T++;
int16_t **v = malloc(T * sizeof(*v));
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
k=0;
for (int i = 0; i <= T-1; i++) {
for (int j = 0; j <= (T-1)-i; j++) {
if (k<E) {
v[i][j] = k;
} else {
v[i][j] = (-1);
}
k++;
}
}
k=0;
for (int j = 0; j <= T-1; j++) {
for (int i = 0; i <= (T-1)-j; i++) {
if ( v[i][j] != (-1) ) {
cip[k]=v[i][j];
k++;
}
}
}
for (int i = 0; i <= T-1; i++) free(v[i]);
free(v);
} else {
for (int i=0; i<=E-1; i++) cip[i]=i;
}
}
...@@ -247,16 +247,16 @@ int8_t polar_decoder( ...@@ -247,16 +247,16 @@ int8_t polar_decoder(
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
if ( crcState[listIndex[i]] == 1 ) { if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[j][0][listIndex[i]]; for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
//Extract the information bits (û to ĉ) //Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b) //Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â) //Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_a[j]=polarParams->nr_polar_b[j]; for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
break; break;
} }
...@@ -274,7 +274,7 @@ int8_t polar_decoder( ...@@ -274,7 +274,7 @@ int8_t polar_decoder(
/* /*
* Return bits. * Return bits.
*/ */
nr_byte2bit_uint8_32_t(polarParams->nr_polar_a, polarParams->payloadBits, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0); return(0);
} }
...@@ -500,16 +500,16 @@ int8_t polar_decoder_aPriori( ...@@ -500,16 +500,16 @@ int8_t polar_decoder_aPriori(
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
if ( crcState[listIndex[i]] == 1 ) { if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[j][0][listIndex[i]]; for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
//Extract the information bits (û to ĉ) //Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b) //Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â) //Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_a[j]=polarParams->nr_polar_b[j]; for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
break; break;
} }
...@@ -527,6 +527,6 @@ int8_t polar_decoder_aPriori( ...@@ -527,6 +527,6 @@ int8_t polar_decoder_aPriori(
/* /*
* Return bits. * Return bits.
*/ */
nr_byte2bit_uint8_32_t(polarParams->nr_polar_a, polarParams->payloadBits, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0); return(0);
} }
...@@ -19,10 +19,30 @@ ...@@ -19,10 +19,30 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*!\file PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, void updateLLR(double ***llr,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
uint8_t approximation)
{
uint16_t offset = (xlen/(pow(2,(ylen-col-1)))); uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
for (uint8_t i=0; i<listSize; i++) { for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) { if (( (row) % (2*offset) ) >= offset ) {
...@@ -40,8 +60,14 @@ void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, ...@@ -40,8 +60,14 @@ void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU,
llrU[row][col]=1; llrU[row][col]=1;
} }
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, void updateBit(uint8_t ***bit,
uint16_t col, uint16_t xlen, uint8_t ylen) { 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))) ); uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) { for (uint8_t i=0; i<listSize; i++) {
...@@ -58,9 +84,13 @@ void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, ...@@ -58,9 +84,13 @@ void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row,
bitU[row][col]=1; bitU[row][col]=1;
} }
void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8_t bitValue, void updatePathMetric(double *pathMetric,
uint16_t row, uint8_t approximation) { double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
uint8_t approximation)
{
if (approximation) { //eq. (12) if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) { for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,llr[row][0][i]) )) pathMetric[i] += fabs(llr[row][0][i]); if ((2*bitValue) != ( 1 - copysign(1.0,llr[row][0][i]) )) pathMetric[i] += fabs(llr[row][0][i]);
...@@ -69,11 +99,14 @@ void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8 ...@@ -69,11 +99,14 @@ void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8
int8_t multiplier = (2*bitValue) - 1; int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) pathMetric[i] += log ( 1 + exp(multiplier*llr[row][0][i]) ) ; for (uint8_t i=0; i<listSize; i++) pathMetric[i] += log ( 1 + exp(multiplier*llr[row][0][i]) ) ;
} }
} }
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint16_t row, uint8_t appr) { void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row,
uint8_t appr)
{
double *tempPM = malloc(sizeof(double) * listSize); double *tempPM = malloc(sizeof(double) * listSize);
for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i]; for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i];
...@@ -101,9 +134,13 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint ...@@ -101,9 +134,13 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint
} }
void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i, void computeLLR(double ***llr,
uint16_t offset, uint8_t approximation) { uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
uint8_t approximation)
{
double a = llr[row][col + 1][i]; double a = llr[row][col + 1][i];
double absA = fabs(a); double absA = fabs(a);
double b = llr[row + offset][col + 1][i]; double b = llr[row + offset][col + 1][i];
...@@ -117,8 +154,12 @@ void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i, ...@@ -117,8 +154,12 @@ void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i,
} }
void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t listSize, uint32_t i2, uint8_t len) { uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) { for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) { for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 ); crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
...@@ -126,8 +167,12 @@ void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, ...@@ -126,8 +167,12 @@ void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen,
} }
} }
void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen, void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t listSize, uint32_t i2, uint8_t len) { uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) { for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) { for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 ); crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
......
...@@ -46,11 +46,17 @@ ...@@ -46,11 +46,17 @@
#define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t #define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t
#define NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12) #define NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_4_PRIME 157 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 //uint16_t
static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 }; static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 };
struct nrPolar_params { struct nrPolar_params {
//messageType: 0=PBCH, 1=DCI, -1=UCI //messageType: 0=PBCH, 1=DCI, -1=UCI
int8_t idx; //idx = messageType*messageLength; int idx; //idx = (messageType * messageLength * aggregation_prime);
struct nrPolar_params *nextPtr; struct nrPolar_params *nextPtr;
uint8_t n_max; uint8_t n_max;
...@@ -66,6 +72,7 @@ struct nrPolar_params { ...@@ -66,6 +72,7 @@ struct nrPolar_params {
uint16_t K; uint16_t K;
uint16_t N; uint16_t N;
uint8_t n; uint8_t n;
uint32_t crcBit;
uint16_t *interleaving_pattern; uint16_t *interleaving_pattern;
uint16_t *rate_matching_pattern; uint16_t *rate_matching_pattern;
...@@ -79,27 +86,37 @@ struct nrPolar_params { ...@@ -79,27 +86,37 @@ struct nrPolar_params {
uint8_t **crc_generator_matrix; //G_P uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N; uint8_t **G_N;
//lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors //polar_encoder vectors
uint8_t *nr_polar_crc; uint8_t *nr_polar_crc;
uint8_t *nr_polar_d; uint8_t *nr_polar_aPrime;
uint8_t *nr_polar_e; uint8_t *nr_polar_D;
uint8_t *nr_polar_E;
//Polar Coding vectors //Polar Coding vectors
uint8_t *nr_polar_a; uint8_t *nr_polar_A;
uint8_t *nr_polar_cPrime; uint8_t *nr_polar_CPrime;
uint8_t *nr_polar_b; uint8_t *nr_polar_B;
uint8_t *nr_polar_u; uint8_t *nr_polar_U;
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params; typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr; typedef t_nrPolar_params *t_nrPolar_paramsPtr;
void polar_encoder(uint32_t *input, uint32_t *output, t_nrPolar_paramsPtr polarParams); void polar_encoder(uint32_t *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams);
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint16_t n_RNTI);
int8_t polar_decoder(double *input, int8_t polar_decoder(double *input,
uint32_t *output, uint32_t *output,
t_nrPolar_paramsPtr polarParams, t_nrPolar_paramsPtr polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr); uint8_t pathMetricAppr);
int8_t polar_decoder_aPriori(double *input, int8_t polar_decoder_aPriori(double *input,
uint32_t *output, uint32_t *output,
t_nrPolar_paramsPtr polarParams, t_nrPolar_paramsPtr polarParams,
...@@ -111,83 +128,189 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams, ...@@ -111,83 +128,189 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level); uint8_t aggregation_level);
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams); void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams);
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams, t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType, int8_t messageType,
uint16_t messageLength); uint16_t messageLength,
uint8_t aggregation_level);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
uint8_t** nr_polar_kronecker_power_matrices(uint8_t n); uint8_t** nr_polar_kronecker_power_matrices(uint8_t n);
const uint16_t* nr_polar_sequence_pattern(uint8_t n); const uint16_t* nr_polar_sequence_pattern(uint8_t n);
uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max); /*!@fn uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max)
* @brief Computes...
void nr_polar_channel_interleaver_pattern(uint16_t *cip, uint8_t I_BIL, * @param K Number of bits to encode (=payloadBits+crcParityBits)
* @param E
* @param n_max */
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max);
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL,
uint16_t E); uint16_t E);
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t K, uint16_t N, uint16_t E); uint16_t *J,
const uint8_t *P_i_,
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K,
uint16_t K, uint16_t N, uint16_t E); uint16_t N,
uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_); void nr_polar_rate_matching(double *input,
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N, void nr_polar_interleaving_pattern(uint16_t K,
uint16_t *J, const uint16_t *Q_0_Nminus1, uint16_t K, uint16_t N, uint16_t E, uint8_t I_IL,
uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC); uint8_t n_PC);
void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *pattern, uint16_t size); uint8_t *output,
uint8_t *pattern,
uint16_t size);
void nr_bit2byte_uint32_8_t(uint32_t *in,
uint16_t arraySize,
uint8_t *out);
void nr_byte2bit_uint8_32_t(uint8_t *in,
uint16_t arraySize,
uint32_t *out);
void nr_crc_bit2bit_uint32_8_t(uint32_t *in,
uint16_t arraySize,
uint8_t *out);
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC);
void nr_bit2byte_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out); void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1,
void nr_byte2bit_uint8_32_t(uint8_t *in, uint16_t arraySize, uint32_t *out); uint8_t **matrix2,
uint8_t *output,
uint16_t row,
uint16_t col);
void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen,
uint16_t K, int16_t *Q_I_N, int16_t *Q_PC_N, uint8_t n_PC); uint16_t ylen,
uint16_t zlen);
void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **matrix2, uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen,
uint8_t *output, uint16_t row, uint16_t col); uint16_t ylen);
uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, double ***nr_alloc_double_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen); uint16_t zlen);
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen); void nr_free_uint8_t_3D_array(uint8_t ***input,
uint16_t xlen,
void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen); uint16_t ylen);
void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen);
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_2D_array(uint8_t **input,
uint16_t xlen);
void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, void nr_free_double_3D_array(double ***input,
uint8_t ylen, uint8_t approximation); uint16_t xlen,
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t ylen);
uint16_t col, uint16_t xlen, uint8_t ylen);
void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, void updateLLR(double ***llr,
uint8_t bitValue, uint16_t row, uint8_t approximation); uint8_t **llrU,
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint8_t ***bit,
uint16_t row, uint8_t approximation); uint8_t **bitU,
void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i, uint8_t listSize,
uint16_t offset, uint8_t approximation); uint16_t row,
void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, uint16_t col,
uint8_t listSize, uint32_t i2, uint8_t len); uint16_t xlen,
void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen, uint8_t ylen,
uint8_t listSize, uint32_t i2, uint8_t len); uint8_t approximation);
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len);
void updateBit(uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen);
void updatePathMetric(double *pathMetric,
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
uint8_t approximation);
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row,
uint8_t approximation);
void computeLLR(double ***llr,
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
uint8_t approximation);
void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
void nr_sort_asc_double_1D_array_ind(double *matrix,
uint8_t *ind,
uint8_t len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
static inline void nr_polar_rate_matcher(uint8_t *input, unsigned char *output, uint16_t *pattern, uint16_t size) { uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
for (int i=0; i<size; i++) output[i]=input[pattern[i]];
}
static inline void nr_polar_interleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size) { //Also nr_polar_rate_matcher
static inline void nr_polar_interleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{
for (int i=0; i<size; i++) output[i]=input[pattern[i]]; for (int i=0; i<size; i++) output[i]=input[pattern[i]];
} }
static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size) { static inline void nr_polar_deinterleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{
for (int i=0; i<size; i++) output[pattern[i]]=input[i]; for (int i=0; i<size; i++) output[pattern[i]]=input[i];
} }
......
...@@ -30,19 +30,21 @@ ...@@ -30,19 +30,21 @@
* \warning * \warning
*/ */
#define DEBUG_POLAR_ENCODER_DCI
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void polar_encoder(uint32_t *in, void polar_encoder(uint32_t *in,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams) t_nrPolar_paramsPtr polarParams)
{ {
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_a); if (polarParams->idx == 0){//PBCH
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
/* /*
* Bytewise operations * Bytewise operations
*/ */
//Calculate CRC. //Calculate CRC.
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_a, nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A,
polarParams->crc_generator_matrix, polarParams->crc_generator_matrix,
polarParams->nr_polar_crc, polarParams->nr_polar_crc,
polarParams->payloadBits, polarParams->payloadBits,
...@@ -51,19 +53,104 @@ void polar_encoder(uint32_t *in, ...@@ -51,19 +53,104 @@ void polar_encoder(uint32_t *in,
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2); polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b) //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 = 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++) for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_b[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)]; 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)
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);
}
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
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
//(a to a')
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
//Parity bits computation (p)
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime,
(polarParams->payloadBits+polarParams->crcParityBits));
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
#endif
//(a to b)
/*
* Bytewise operations
*/
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);
}
}
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;
}
//Scrambling (b to c)
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;
}
#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
//Interleaving (c to c') //Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_b, nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_cPrime, polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern, polarParams->interleaving_pattern,
polarParams->K); polarParams->K);
//Bit insertion (c' to u) //Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_cPrime, nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_u, polarParams->nr_polar_U,
polarParams->N, polarParams->N,
polarParams->K, polarParams->K,
polarParams->Q_I_N, polarParams->Q_I_N,
...@@ -71,23 +158,32 @@ void polar_encoder(uint32_t *in, ...@@ -71,23 +158,32 @@ void polar_encoder(uint32_t *in,
polarParams->n_pc); polarParams->n_pc);
//Encoding (u to d) //Encoding (u to d)
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_u, nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
polarParams->G_N, polarParams->G_N,
polarParams->nr_polar_d, polarParams->nr_polar_D,
polarParams->N, polarParams->N,
polarParams->N); polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++) for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_d[i] = (polarParams->nr_polar_d[i] % 2); polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
//Rate matching //Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e) //Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_rate_matcher(polarParams->nr_polar_d, nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_e, polarParams->nr_polar_E,
polarParams->rate_matching_pattern, polarParams->rate_matching_pattern,
polarParams->encoderLength); polarParams->encoderLength);
/* /*
* Return bits. * Return bits.
*/ */
nr_byte2bit_uint8_32_t(polarParams->nr_polar_e, polarParams->encoderLength, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
#ifdef DEBUG_POLAR_ENCODER_DCI
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]);
}
#endif
} }
...@@ -19,6 +19,17 @@ ...@@ -19,6 +19,17 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*!\file PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){ void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){
......
...@@ -19,6 +19,17 @@ ...@@ -19,6 +19,17 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*!\file PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
uint8_t (*const(G_N_1[])) = { uint8_t (*const(G_N_1[])) = {
...@@ -19,6 +19,17 @@ ...@@ -19,6 +19,17 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*!\file PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **matrix2, void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **matrix2,
......
/*
* 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
*/
#include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max){
uint8_t n_1, n_2, n_min=5, n;
uint32_t polar_code_output_length;
double R_min=1.0/8;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
n_1 = ceil(log2(E))-1;
} else {
n_1 = ceil(log2(E));
}
n_2 = ceil(log2(K/R_min));
n=n_max;
if (n>n_1) n=n_1;
if (n>n_2) n=n_2;
if (n<n_min) n=n_min;
polar_code_output_length = (uint32_t) pow(2.0,n);
return polar_code_output_length;
}
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*!\file PHY/CODING/nrPolar_tools/nr_polar_defs.h /*!\file PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h
* \brief Defines the constant variables for polar coding of the PBCH from 38-212, V15.1.1 2018-04. * \brief Defines the constant variables for polar coding of the PBCH from 38-212, V15.1.1 2018-04.
* \author Turker Yilmaz * \author Turker Yilmaz
* \date 2018 * \date 2018
......
...@@ -19,12 +19,132 @@ ...@@ -19,12 +19,132 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*!\file PHY/CODING/nrPolar_tools/nr_polar_procedures.h
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N, void nr_polar_bit_insertion(uint8_t *input,
uint16_t *J, const uint16_t *Q_0_Nminus1, uint16_t K, uint16_t N, uint16_t E, uint8_t *output,
uint8_t n_PC) { uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC)
{
uint16_t k=0;
uint8_t flag;
if (n_PC>0) {
/*
*
*/
} else {
for (int n=0; n<=N-1; n++) {
flag=0;
for (int m=0; m<=(K+n_PC)-1; m++) {
if ( n == Q_I_N[m]) {
flag=1;
break;
}
}
if (flag) { // n ϵ Q_I_N
output[n]=input[k];
k++;
} else {
output[n] = 0;
}
}
}
}
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max)
{
uint8_t n_1, n_2, n_min=5, n;
double R_min=1.0/8;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
n_1 = ceil(log2(E))-1;
} else {
n_1 = ceil(log2(E));
}
n_2 = ceil(log2(K/R_min));
n=n_max;
if (n>n_1) n=n_1;
if (n>n_2) n=n_2;
if (n<n_min) n=n_min;
return ((uint32_t) pow(2.0,n)); //=polar_code_output_length
}
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL,
uint16_t E)
{
if (I_BIL == 1) {
uint16_t T=0, k;
while( ((T/2)*(T+1)) < E ) T++;
int16_t **v = malloc(T * sizeof(*v));
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
k=0;
for (int i = 0; i <= T-1; i++) {
for (int j = 0; j <= (T-1)-i; j++) {
if (k<E) {
v[i][j] = k;
} else {
v[i][j] = (-1);
}
k++;
}
}
k=0;
for (int j = 0; j <= T-1; j++) {
for (int i = 0; i <= (T-1)-j; i++) {
if ( v[i][j] != (-1) ) {
cip[k]=v[i][j];
k++;
}
}
}
for (int i = 0; i <= T-1; i++) free(v[i]);
free(v);
} else {
for (int i=0; i<=E-1; i++) cip[i]=i;
}
}
void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC)
{
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value. int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
...@@ -120,7 +240,12 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N, ...@@ -120,7 +240,12 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N,
free(Q_Itmp_N); free(Q_Itmp_N);
} }
void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *pattern, uint16_t size) {
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
uint8_t *pattern,
uint16_t size)
{
uint16_t j = 0; uint16_t j = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (pattern[i] > 0) { if (pattern[i] > 0) {
...@@ -129,3 +254,62 @@ void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *patt ...@@ -129,3 +254,62 @@ void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *patt
} }
} }
} }
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E){
uint8_t i;
uint16_t *d, *y, ind;
d = (uint16_t *)malloc(sizeof(uint16_t) * N);
y = (uint16_t *)malloc(sizeof(uint16_t) * N);
for (int m=0; m<=N-1; m++) d[m]=m;
for (int m=0; m<=N-1; m++){
i=floor((32*m)/N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
y[m] = d[J[m]];
}
if (E>=N) { //repetition
for (int k=0; k<=E-1; k++) {
ind = (k%N);
rmp[k]=y[ind];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k+N-E];
}
} else { //shortening
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k];
}
}
}
free(d);
free(y);
}
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
}
/*
* 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
*/
#include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E){
uint8_t i;
uint16_t *d, *y, ind;
d = (uint16_t *)malloc(sizeof(uint16_t) * N);
y = (uint16_t *)malloc(sizeof(uint16_t) * N);
for (int m=0; m<=N-1; m++) d[m]=m;
for (int m=0; m<=N-1; m++){
i=floor((32*m)/N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
y[m] = d[J[m]];
}
if (E>=N) { //repetition
for (int k=0; k<=E-1; k++) {
ind = (k%N);
rmp[k]=y[ind];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k+N-E];
}
} else { //shortening
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k];
}
}
}
free(d);
free(y);
}
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
}
...@@ -42,10 +42,11 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams, ...@@ -42,10 +42,11 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
uint8_t aggregation_level) uint8_t aggregation_level)
{ {
t_nrPolar_paramsPtr currentPtr = *polarParams; t_nrPolar_paramsPtr currentPtr = *polarParams;
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization. //Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) { while (currentPtr != NULL) {
if (currentPtr->idx == (messageType * messageLength)) return; if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr; else currentPtr = currentPtr->nextPtr;
} }
...@@ -54,7 +55,7 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams, ...@@ -54,7 +55,7 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
if (newPolarInitNode != NULL) { if (newPolarInitNode != NULL) {
newPolarInitNode->idx = (messageType * messageLength); newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL; newPolarInitNode->nextPtr = NULL;
if (messageType == 0) { //PBCH if (messageType == 0) { //PBCH
...@@ -94,14 +95,15 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams, ...@@ -94,14 +95,15 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
//polar_encoder vectors: //polar_encoder vectors:
newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits); newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits);
newPolarInitNode->nr_polar_d = malloc(sizeof(uint8_t) * newPolarInitNode->N); newPolarInitNode->nr_polar_aPrime = malloc(sizeof(uint8_t) * ((ceil((newPolarInitNode->payloadBits)/32.0)*4)+3));
newPolarInitNode->nr_polar_e = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength); newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength);
//Polar Coding vectors //Polar Coding vectors
newPolarInitNode->nr_polar_u = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat
newPolarInitNode->nr_polar_cPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat
newPolarInitNode->nr_polar_b = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat newPolarInitNode->nr_polar_B = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat
newPolarInitNode->nr_polar_a = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat newPolarInitNode->nr_polar_A = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat
...@@ -180,12 +182,14 @@ void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams) ...@@ -180,12 +182,14 @@ void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams)
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams, t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType, int8_t messageType,
uint16_t messageLength) uint16_t messageLength,
uint8_t aggregation_level)
{ {
t_nrPolar_paramsPtr currentPtr = NULL; t_nrPolar_paramsPtr currentPtr = NULL;
while (polarParams != NULL) { while (polarParams != NULL) {
if (polarParams->idx == (messageType * messageLength)) { if (polarParams->idx ==
(messageType * messageLength * (nr_polar_aggregation_prime(aggregation_level)) )) {
currentPtr = polarParams; currentPtr = polarParams;
break; break;
} else { } else {
...@@ -194,3 +198,13 @@ t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams, ...@@ -194,3 +198,13 @@ t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
} }
return currentPtr; return currentPtr;
} }
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level)
{
if (aggregation_level == 0) return 0;
else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME;
else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_PRIME;
else if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME;
else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16
}
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
//#define DEBUG_PDCCH_DMRS //#define DEBUG_PDCCH_DMRS
//#define DEBUG_DCI //#define DEBUG_DCI
#define DEBUG_POLAR_PARAMS //#define DEBUG_POLAR_PARAMS
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
...@@ -202,40 +202,29 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, ...@@ -202,40 +202,29 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
} }
/// DCI payload processing /// DCI payload processing
//channel coding // CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti : 0;
nr_polar_init(nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); nr_polar_init(nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size); t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
polar_encoder_dci(dci_alloc.dci_pdu, encoder_output, currentPtr, n_RNTI);
uint8_t *encoderInput = malloc(sizeof(uint8_t) * dci_alloc.size);
uint8_t *encoderOutput = malloc(sizeof(uint8_t) * currentPtr->encoderLength);
uint32_t encoded_payload[4];
nr_bit2byte_uint32_8_t(dci_alloc.dci_pdu,dci_alloc.size,encoderInput);
polar_encoder(encoderInput, encoderOutput, currentPtr);
nr_byte2bit_uint8_32_t(encoderOutput, currentPtr->encoderLength, encoded_payload);
#ifdef DEBUG_POLAR_PARAMS #ifdef DEBUG_POLAR_PARAMS
printf("DCI PDU: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", /*printf("DCI PDU: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1], dci_alloc.dci_pdu[2], dci_alloc.dci_pdu[3]); dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1], dci_alloc.dci_pdu[2], dci_alloc.dci_pdu[3]);
printf("Encoded Payload: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", printf("Encoded Payload: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
encoded_payload[0], encoded_payload[1], encoded_payload[2], encoded_payload[3]); encoder_output[0], encoder_output[1], encoder_output[2], encoder_output[3]);*/
#endif #endif
// scrambling
uint32_t scrambled_payload[NR_MAX_DCI_SIZE_DWORD];
uint32_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
uint32_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti : 0;
nr_pdcch_scrambling(encoded_payload, dci_alloc.size, Nid, n_RNTI, scrambled_payload);
// QPSK modulation // QPSK modulation
int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
for (int i=0; i<encoded_length>>1; i++) { for (int i=0; i<encoded_length>>1; i++) {
idx = (((scrambled_payload[i<<1]>>(i<<1))&1)<<1) ^ ((scrambled_payload[(i<<1)+1]>>((i<<1)+1))&1); idx = (((encoder_output[i<<1]>>(i<<1))&1)<<1) ^ ((encoder_output[(i<<1)+1]>>((i<<1)+1))&1);
mod_dci[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; mod_dci[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dci[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; mod_dci[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
printf("i %d idx %d b0-b1 %d-%d mod_dci %d %d\n", i, idx, (((scrambled_payload[(i<<1)>>5])>>((i<<1)&0x1f))&1), printf("i %d idx %d b0-b1 %d-%d mod_dci %d %d\n", i, idx, (((encoder_output[(i<<1)>>5])>>((i<<1)&0x1f))&1),
(((scrambled_payload[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dci[(i<<1)], mod_dci[(i<<1)+1]); (((encoder_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dci[(i<<1)], mod_dci[(i<<1)+1]);
#endif #endif
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
*/ */
#include "nr_dci.h" #include "nr_dci.h"
#define DEBUG_NFAPI_NR_RNTI_RA //#define DEBUG_NFAPI_NR_RNTI_RA
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) { void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) {
...@@ -129,19 +129,22 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, ...@@ -129,19 +129,22 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
case NFAPI_NR_DL_DCI_FORMAT_1_0: case NFAPI_NR_DL_DCI_FORMAT_1_0:
switch(params_rel15->rnti_type) { switch(params_rel15->rnti_type) {
case NFAPI_NR_RNTI_RA: case NFAPI_NR_RNTI_RA:
#ifdef DEBUG_NFAPI_NR_RNTI_RA // Freq domain assignment
printf("frequency_domain_assignment = %05d = %#010x\n" fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
#ifdef DEBUG_NFAPI_NR_RNTI_RA
printf("frequency_domain_assignment = %05d = %#010x\n"
" time_domain_assignment = %05d = %#010x\n" " time_domain_assignment = %05d = %#010x\n"
" vrb_to_prb_mapping = %05d = %#010x\n" " vrb_to_prb_mapping = %05d = %#010x\n"
" MCS = %05d = %#010x\n" " MCS = %05d = %#010x\n"
" tb_scaling = %05d = %#010x\n", " tb_scaling = %05d = %#010x\n"
" N_RB = %05d = %#010x\n"
" fsize = %05d = %#010x\n",
pdu_rel15->frequency_domain_assignment,pdu_rel15->frequency_domain_assignment, pdu_rel15->frequency_domain_assignment,pdu_rel15->frequency_domain_assignment,
pdu_rel15->time_domain_assignment,pdu_rel15->time_domain_assignment, pdu_rel15->time_domain_assignment,pdu_rel15->time_domain_assignment,
pdu_rel15->vrb_to_prb_mapping,pdu_rel15->vrb_to_prb_mapping, pdu_rel15->vrb_to_prb_mapping,pdu_rel15->vrb_to_prb_mapping,
pdu_rel15->mcs,pdu_rel15->mcs,pdu_rel15->tb_scaling,pdu_rel15->tb_scaling); pdu_rel15->mcs,pdu_rel15->mcs,pdu_rel15->tb_scaling,pdu_rel15->tb_scaling,
#endif N_RB,N_RB,fsize,fsize);
// Freq domain assignment #endif
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
for (int i=0; i<fsize; i++) for (int i=0; i<fsize; i++)
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<pos++; *dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<pos++;
// Time domain assignment // Time domain assignment
...@@ -155,9 +158,7 @@ printf("frequency_domain_assignment = %05d = %#010x\n" ...@@ -155,9 +158,7 @@ printf("frequency_domain_assignment = %05d = %#010x\n"
// TB scaling // TB scaling
for (int i=0; i<2; i++) for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->tb_scaling>>(1-i))&1)<<pos++; *dci_pdu |= ((pdu_rel15->tb_scaling>>(1-i))&1)<<pos++;
break; break;
} }
break; break;
......
...@@ -888,6 +888,7 @@ static void wait_nfapi_init(char *thread_name) { ...@@ -888,6 +888,7 @@ static void wait_nfapi_init(char *thread_name) {
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
crcTableInit();
int i; int i;
#if defined (XFORMS) #if defined (XFORMS)
//void *status; //void *status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment