Commit 92ba679b authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/develop-PUCCH2' into integration_2023_w28

parents 52f21f52 1d6f740c
......@@ -271,7 +271,7 @@ The following features are valid for the gNB and the 5G-NR UE.
- Support for 256 QAM
* NR-PUCCH
- Format 0 (2 bits, for ACK/NACK and SR)
- Format 2 (up to 11 bits, mainly for CSI feedback)
- Format 2 (mainly for CSI feedback)
* NR-SRS
- SRS signal reception
- Channel estimation (with T tracer real time monitoring)
......@@ -443,7 +443,7 @@ The following features are valid for the gNB and the 5G-NR UE.
- Support for up to 2 layers
* NR-PUCCH
- Format 0 (2 bits for ACK/NACK and SR)
- Format 2 (up to 11 bits, mainly for CSI feedback)
- Format 2 (mainly for CSI feedback)
- Format 1 (limited testing)
- Format 3 and 4 present but old code never tested (need restructuring before verification)
* NR-SRS
......
......@@ -39,6 +39,8 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "assertions.h"
//#define POLAR_CODING_DEBUG
static inline void updateCrcChecksum2(int xlen,
int ylen,
uint8_t crcChecksum[xlen][ylen],
......@@ -611,24 +613,78 @@ uint32_t polar_decoder_int16(int16_t *input,
uint8_t aggregation_level )
{
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
#ifdef POLAR_CODING_DEBUG
printf("\nRX\n");
printf("rm:");
for (int i = 0; i < polarParams->N; i++) {
if (i % 4 == 0) {
printf(" ");
}
printf("%i", input[i] < 0 ? 1 : 0);
}
printf("\n");
#endif
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength, polarParams->i_bil);
for (int i=0; i<polarParams->N; i++) {
if (d_tilde[i]<-128) d_tilde[i]=-128;
else if (d_tilde[i]>127) d_tilde[i]=128;
}
memcpy((void *)&polarParams->tree.root->alpha[0],(void *)&d_tilde[0],sizeof(int16_t)*polarParams->N);
generic_polar_decoder(polarParams,polarParams->tree.root);
//Extract the information bits (û to ĉ)
uint64_t Cprime[4]= {0,0,0,0};
uint64_t B[4]= {0,0,0,0};
#ifdef POLAR_CODING_DEBUG
printf("d: ");
for (int i = 0; i < polarParams->N; i++) {
if (i % 4 == 0) {
printf(" ");
}
printf("%i", d_tilde[i] < 0 ? 1 : 0);
}
printf("\n");
#endif
memcpy((void *)&polarParams->tree.root->alpha[0], (void *)&d_tilde[0], sizeof(int16_t) * polarParams->N);
memset(polarParams->nr_polar_U, 0, polarParams->N * sizeof(uint8_t));
generic_polar_decoder(polarParams, polarParams->tree.root);
for (int i=0; i<polarParams->K; i++) Cprime[i>>6] = Cprime[i>>6] | ((uint64_t)polarParams->nr_polar_U[polarParams->Q_I_N[i]])<<(i&63);
#ifdef POLAR_CODING_DEBUG
printf("u: ");
for (int i = 0; i < polarParams->N; i++) {
if (i % 4 == 0) {
printf(" ");
}
printf("%i", polarParams->nr_polar_U[i]);
}
printf("\n");
#endif
// Extract the information bits (û to ĉ)
uint64_t Cprime[4]= {0};
nr_polar_info_extraction_from_u(Cprime,
polarParams->nr_polar_U,
polarParams->information_bit_pattern,
polarParams->parity_check_bit_pattern,
polarParams->N,
polarParams->n_pc);
#ifdef POLAR_CODING_DEBUG
printf("c: ");
for (int n = 0; n < polarParams->K; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
printf("%lu", (Cprime[n1] >> n2) & 1);
}
printf("\n");
#endif
//Deinterleaving (ĉ to b)
uint8_t *Cprimebyte = (uint8_t *)Cprime;
uint64_t B[4] = {0};
if (polarParams->K<65) {
B[0] = polarParams->B_tab0[0][Cprimebyte[0]] |
......@@ -650,6 +706,21 @@ uint32_t polar_decoder_int16(int16_t *input,
}
}
#ifdef POLAR_CODING_DEBUG
int B_array = (polarParams->K + 63) >> 6;
int n_start = (B_array << 6) - polarParams->K;
printf("b: ");
for (int n = 0; n < polarParams->K; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = (n + n_start) >> 6;
int n2 = (n + n_start) - (n1 << 6);
printf("%lu", (B[B_array - 1 - n1] >> (63 - n2)) & 1);
}
printf("\n");
#endif
int len=polarParams->payloadBits;
//int len_mod64=len&63;
int crclen = polarParams->crcParityBits;
......@@ -700,6 +771,21 @@ uint32_t polar_decoder_int16(int16_t *input,
else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f;
}
#ifdef POLAR_CODING_DEBUG
int A_array = (len + 63) >> 6;
printf("a: ");
for (int n = 0; n < len; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
int alen = n1 == 0 ? len - (A_array << 6) : 64;
printf("%lu", (Ar >> (alen - 1 - n2)) & 1);
}
printf("\n\n");
#endif
#if 0
printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n",
Ar,
......
......@@ -106,6 +106,7 @@ struct nrPolar_params {
int16_t *Q_F_N;
int16_t *Q_PC_N;
uint8_t *information_bit_pattern;
uint8_t *parity_check_bit_pattern;
uint16_t *channel_interleaver_pattern;
//uint32_t crc_polynomial;
......@@ -238,24 +239,28 @@ void nr_polar_rate_matching(double *input,
void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
const uint16_t *rmp,
const uint16_t K,
const uint16_t N,
const uint16_t E,
const uint8_t i_bil);
void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL,
uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp,
uint8_t *pcbp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
int16_t *Q_PC_N,
const 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,
uint8_t n_pc_wm);
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
......@@ -272,6 +277,22 @@ void nr_byte2bit_uint8_32(uint8_t *in,
const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
void nr_polar_generate_u(uint64_t *u,
const uint64_t *Cprime,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc);
void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N);
void nr_polar_info_extraction_from_u(uint64_t *Cprime,
const uint8_t *u,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc);
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
......
......@@ -33,6 +33,7 @@
//#define DEBUG_POLAR_ENCODER
//#define DEBUG_POLAR_ENCODER_DCI
//#define DEBUG_POLAR_MATLAB
//#define POLAR_CODING_DEBUG
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "assertions.h"
......@@ -262,6 +263,44 @@ void polar_encoder_dci(uint32_t *in,
polarReturn;
}
/*
* Interleaving of coded bits implementation
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
*/
void nr_polar_rm_interleaving_cb(void *in, void *out, uint16_t E)
{
int T = ceil((sqrt(8 * E + 1) - 1) / 2);
int v[T][T];
int k = 0;
uint64_t *in64 = (uint64_t *)in;
for (int i = 0; i < T; i++) {
for (int j = 0; j < T - i; j++) {
if (k < E) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
v[i][j] = (in64[k1] >> k2) & 1;
} else {
v[i][j] = -1;
}
k++;
}
}
k = 0;
uint64_t *out64 = (uint64_t *)out;
memset(out64, 0, E >> 3);
for (int j = 0; j < T; j++) {
for (int i = 0; i < T - j; i++) {
if (v[i][j] != -1) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
out64[k1] |= (uint64_t)v[i][j] << k2;
k++;
}
}
}
}
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) {
......@@ -309,6 +348,10 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void
for (int i=0; i<polarParams->encoderLength>>4; i++) {
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
}
if (polarParams->i_bil == 1) {
nr_polar_rm_interleaving_cb(out, out, polarParams->encoderLength);
}
}
void build_polar_tables(t_nrPolar_params *polarParams) {
......@@ -344,28 +387,27 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
AssertFatal(polarParams->N == 512 || polarParams->N == 256 || polarParams->N == 128 || polarParams->N == 64, "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
polarParams->G_N_tab = (uint64_t **)calloc((polarParams->K + polarParams->n_pc),sizeof(int64_t *));
int k=0;
// 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.
polarParams->G_N_tab = (uint64_t **)calloc(polarParams->N, sizeof(int64_t *));
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 i = 0; i < polarParams->N; i++) {
polarParams->G_N_tab[i] = (uint64_t *)memalign(32, (polarParams->N / 64) * sizeof(uint64_t));
memset((void *)polarParams->G_N_tab[i], 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);
for (int j = 0; j < polarParams->N; j++)
polarParams->G_N_tab[i][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);
printf("Bit %d Selecting row %d of G : ", i, 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));
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");
printf("\n");
#endif
k++;
}
}
// rate matching table
......@@ -452,6 +494,21 @@ void polar_encoder_fast(uint64_t *A,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
#ifdef POLAR_CODING_DEBUG
printf("polarParams->payloadBits = %i\n", polarParams->payloadBits);
printf("polarParams->crcParityBits = %i\n", polarParams->crcParityBits);
printf("polarParams->K = %i\n", polarParams->K);
printf("polarParams->N = %i\n", polarParams->N);
printf("polarParams->encoderLength = %i\n", polarParams->encoderLength);
printf("polarParams->n_pc = %i\n", polarParams->n_pc);
printf("polarParams->n_pc_wm = %i\n", polarParams->n_pc_wm);
printf("polarParams->groupsize = %i\n", polarParams->groupsize);
printf("polarParams->i_il = %i\n", polarParams->i_il);
printf("polarParams->i_bil = %i\n", polarParams->i_bil);
printf("polarParams->n_max = %i\n", polarParams->n_max);
#endif
// AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
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);
......@@ -460,6 +517,23 @@ void polar_encoder_fast(uint64_t *A,
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
// AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen;
#ifdef POLAR_CODING_DEBUG
int A_array = (bitlen + 63) >> 6;
printf("\nTX\n");
printf("a: ");
for (int n = 0; n < bitlen; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
int alen = n1 == 0 ? bitlen - (A_array << 6) : 64;
printf("%lu", (A[A_array - 1 - n1] >> (alen - 1 - n2)) & 1);
}
printf("\n");
#endif
uint64_t tcrc=0;
uint8_t offset = 0;
......@@ -526,7 +600,6 @@ void polar_encoder_fast(uint64_t *A,
tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff;
}
int n;
// this is number of quadwords in the bit string
int quadwlen = (polarParams->K+63)/64;
......@@ -536,27 +609,43 @@ void polar_encoder_fast(uint64_t *A,
//??? 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
uint64_t B[4]= {0};
B[0] = (A[0] << polarParams->crcParityBits) | tcrc;
for (n=1; n<quadwlen; n++)
for (int n = 1; n < quadwlen; n++)
if ((bitlen+63)/64 > n)
B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
else
B[n] = (A[n-1]>>(64-polarParams->crcParityBits));
uint8_t *Bbyte = (uint8_t *)B;
#ifdef POLAR_CODING_DEBUG
int bitlen_B = bitlen + polarParams->crcParityBits;
int B_array = (bitlen_B + 63) >> 6;
int n_start = (B_array << 6) - bitlen_B;
printf("b: ");
for (int n = 0; n < bitlen_B; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = (n + n_start) >> 6;
int n2 = (n + n_start) - (n1 << 6);
printf("%lu", (B[B_array - 1 - n1] >> (63 - n2)) & 1);
}
printf("\n");
#endif
// for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
// TS 38.212 - Section 5.3.1.1 Interleaving
// For each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
uint64_t Cprime[4]= {0};
if (polarParams->K<65)
uint8_t *Bbyte = (uint8_t *)B;
if (polarParams->K < 65) {
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
polarParams->cprime_tab0[1][Bbyte[1]] |
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]];
else if (polarParams->K < 129) {
for (int i=0; i<1+(polarParams->K/8); i++) {
} 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]];
}
......@@ -567,165 +656,73 @@ void polar_encoder_fast(uint64_t *A,
for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i]));
#endif
#ifdef DEBUG_POLAR_ENCODER
printf("Polar encoder: (N,K) : (%d,%d)\n",polarParams->N,polarParams->K);
if (polarParams->K<65)
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %lx)\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 %lx)\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);
}
#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]]);*/
// 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 ?
uint64_t Cprime_i;
/* 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]);*/
uint64_t D[8]= {0,0,0,0,0,0,0,0};
int off=0;
int len=polarParams->K;
if (polarParams->N==512) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
/*
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
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]);
#endif
*/
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]);
#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
}
#ifdef POLAR_CODING_DEBUG
printf("c: ");
for (int n = 0; n < bitlen_B; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
printf("%lu", (Cprime[n1] >> n2) & 1);
}
else if (polarParams->N==256) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
/*
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx\n",
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],
#endif
*/
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]);
#ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx,%llx,%llx\n",
D[0],
D[1],
D[2],
D[3]);
printf("\n");
#endif
}
uint64_t u[16] = {0};
nr_polar_generate_u(u,
Cprime,
polarParams->information_bit_pattern,
polarParams->parity_check_bit_pattern,
polarParams->N,
polarParams->n_pc);
#ifdef POLAR_CODING_DEBUG
int N_array = polarParams->N >> 6;
printf("u: ");
for (int n = 0; n < polarParams->N; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
printf("%lu", (u[N_array - 1 - n1] >> (63 - n2)) & 1);
}
else if (polarParams->N==128) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
#ifdef DEBUG_POLAR_ENCODER
printf("%lx Cprime_%d (%d+%d) (%llx) G %llx,%llx\n",
Cprime_i,off+i,off,i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0],
polarParams->G_N_tab[off+i][1]);
#endif
uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]);
D[1] ^= (Cprime_i & Gi[1]);
#ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx\n",
D[0],
D[1]);
printf("\n");
#endif
}
}
} else if (polarParams->N == 64) {
for (int i = 0; i < ((len > 63) ? 64 : len); i++) {
Cprime_i = -((Cprime[0] >> i) & 1);
D[0] ^= (Cprime_i & polarParams->G_N_tab[off + i][0]);
uint64_t D[8] = {0};
nr_polar_uxG(D, u, (const uint64_t **)polarParams->G_N_tab, polarParams->N);
#ifdef POLAR_CODING_DEBUG
printf("d: ");
for (int n = 0; n < polarParams->N; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
printf("%lu", (D[n1] >> n2) & 1);
}
printf("\n");
#endif
memset((void*)out,0,polarParams->encoderLength>>3);
polar_rate_matching(polarParams,(void *)D, out);
polarReturn;
#ifdef POLAR_CODING_DEBUG
uint64_t *out64 = (uint64_t *)out;
printf("rm:");
for (int n = 0; n < polarParams->encoderLength; n++) {
if (n % 4 == 0) {
printf(" ");
}
int n1 = n >> 6;
int n2 = n - (n1 << 6);
printf("%lu", (out64[n1] >> n2) & 1);
}
printf("\n");
#endif
polarReturn;
}
......@@ -32,6 +32,117 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
// TS 38.212 - Section 5.3.1.2 Polar encoding
void nr_polar_generate_u(uint64_t *u,
const uint64_t *Cprime,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc)
{
int N_array = N >> 6;
int k = 0;
if (n_pc > 0) {
uint64_t y0 = 0, y1 = 0, y2 = 0, y3 = 0, y4 = 0;
for (int n = 0; n < N; n++) {
uint64_t yt = y0;
y0 = y1;
y1 = y2;
y2 = y3;
y3 = y4;
y4 = yt;
if (information_bit_pattern[n] == 1) {
int n1 = n >> 6;
int n2 = n - (n1 << 6);
if (parity_check_bit_pattern[n] == 1) {
u[N_array - 1 - n1] |= y0 << (63 - n2);
} else {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
uint64_t bit = (Cprime[k1] >> k2) & 1;
u[N_array - 1 - n1] |= bit << (63 - n2);
k++;
y0 = y0 ^ (int)bit;
}
}
}
} else {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
int n1 = n >> 6;
int n2 = n - (n1 << 6);
int k1 = k >> 6;
int k2 = k - (k1 << 6);
uint64_t bit = (Cprime[k1] >> k2) & 1;
u[N_array - 1 - n1] |= bit << (63 - n2);
k++;
}
}
}
}
void nr_polar_info_extraction_from_u(uint64_t *Cprime,
const uint8_t *u,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc)
{
int k = 0;
if (n_pc > 0) {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
if (parity_check_bit_pattern[n] == 0) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
Cprime[k1] |= (uint64_t)u[n] << k2;
k++;
}
}
}
} else {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
Cprime[k1] |= (uint64_t)u[n] << k2;
k++;
}
}
}
}
void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N)
{
int N_array = N >> 6;
for (int n = 0; n < N; n++) {
const uint64_t *Gn = G_N_tab[N - 1 - n];
int n_ones = 0;
for (int a = 0; a < N_array; a++) {
uint64_t uxG = u[a] & Gn[a];
for (int m = 0; m < 64; m++) {
if (((uxG >> m) & 1) == 1) {
n_ones++;
}
}
}
uint64_t bit = n_ones % 2;
int n1 = n >> 6;
int n2 = n - (n1 << 6);
D[n1] |= bit << n2;
}
}
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
......@@ -138,14 +249,17 @@ void nr_polar_channel_interleaver_pattern(uint16_t *cip,
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 *pcbp,
int16_t *Q_I_N,
int16_t *Q_F_N,
int16_t *Q_PC_N,
const 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_wm)
{
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.
......@@ -159,44 +273,44 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
uint16_t limit, ind;
if (E < N) {
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
if ((K / (double)E) <= (7.0 / 16)) { // puncturing
for (int n = 0; n <= N - E - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
if ((E / (double) N) >= (3.0 / 4)) {
limit = ceil((double) (3 * N - 2 * E) / 4);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
if ((E / (double)N) >= (3.0 / 4)) {
limit = ceil((double)(3 * N - 2 * E) / 4);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
} else {
limit = ceil((double) (9 * N - 4 * E) / 16);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
limit = ceil((double)(9 * N - 4 * E) / 16);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
} else { //shortening
} else { // shortening
for (int n = E; n <= N - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
}
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
// Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
flag = 0;
break;
flag = 0;
break;
}
}
if (flag) {
......@@ -205,19 +319,26 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
}
}
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
// Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
for (int n = 0; n <= (K + n_PC) - 1; n++) {
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
Q_I_N[n] = Q_Itmp_N[ind];
}
//Q_F_N = Q_0_N-1 \ Q_I_N
if (n_PC > 0) {
AssertFatal(n_pc_wm == 0, "Q_PC_N computation for n_pc_wm = %i is not implemented yet!\n", n_pc_wm);
for (int n = 0; n < n_PC - n_pc_wm; n++) {
Q_PC_N[n] = Q_I_N[n];
}
}
// Q_F_N = Q_0_N-1 \ Q_I_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (Q_0_Nminus1[n] == Q_I_N[m]) {
flag = 0;
break;
flag = 0;
break;
}
}
if (flag) {
......@@ -226,16 +347,25 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
}
}
//Information Bit Pattern
// Information and Parity Chack Bit Pattern
for (int n = 0; n <= N - 1; n++) {
ibp[n] = 0;
ibp[n] = 0;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (n == Q_I_N[m]) {
ibp[n] = 1;
break;
ibp[n] = 1;
break;
}
}
pcbp[n] = 0;
for (int m = 0; m < n_PC - n_pc_wm; m++) {
if (n == Q_PC_N[m]) {
pcbp[n] = 1;
break;
}
}
}
free(Q_Ftmp_N);
......@@ -325,23 +455,75 @@ void nr_polar_rate_matching(double *input,
}
}
/*
* De-interleaving of coded bits implementation
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
*/
void nr_polar_rm_deinterleaving_cb(const int16_t *in, int16_t *out, const uint16_t E)
{
int T = ceil((sqrt(8 * E + 1) - 1) / 2);
int v_tab[T][T];
int k = 0;
for (int i = 0; i < T; i++) {
memset(v_tab[i], 0, T * sizeof(int));
for (int j = 0; j < T - i; j++) {
if (k < E) {
v_tab[i][j] = k + 1;
}
k++;
}
}
int v[T][T];
k = 0;
for (int j = 0; j < T; j++) {
for (int i = 0; i < T - j; i++) {
if (k < E && v_tab[i][j] != 0) {
v[i][j] = in[k];
k++;
} else {
v[i][j] = INT_MAX;
}
}
}
k = 0;
memset(out, 0, E * sizeof(int16_t));
for (int i = 0; i < T; i++) {
for (int j = 0; j < T - i; j++) {
if (v[i][j] != INT_MAX) {
out[k] = v[i][j];
k++;
}
}
}
}
void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
int16_t *output,
const uint16_t *rmp,
const uint16_t K,
const uint16_t N,
const uint16_t E,
const uint8_t i_bil)
{
if (E>=N) { //repetition
memset((void*)output,0,N*sizeof(int16_t));
for (int i=0; i<=E-1; i++) output[rmp[i]]+=input[i];
if (i_bil == 1) {
nr_polar_rm_deinterleaving_cb(input, input, E);
}
if (E >= N) { // repetition
memset((void *)output, 0, N * sizeof(int16_t));
for (int i = 0; i <= E - 1; i++)
output[rmp[i]] += input[i];
} else {
if ( (K/(double)E) <= (7.0/16) ) memset((void*)output,0,N*sizeof(int16_t)); //puncturing
else { //shortening
for (int i=0; i<=N-1; i++) output[i]=32767;//instead of INFINITY, to prevent [-Woverflow]
if ((K / (double)E) <= (7.0 / 16))
memset((void *)output, 0, N * sizeof(int16_t)); // puncturing
else { // shortening
for (int i = 0; i <= N - 1; i++)
output[i] = 32767; // instead of INFINITY, to prevent [-Woverflow]
}
for (int i=0; i<=E-1; i++) output[rmp[i]]=input[i];
for (int i = 0; i <= E - 1; i++)
output[rmp[i]] = input[i];
}
}
......@@ -49,9 +49,9 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
delete_decoder_tree(polarParams);
//From build_polar_tables()
for (int k=0; k < polarParams->K + polarParams->n_pc; k++)
if (polarParams->G_N_tab[k])
free(polarParams->G_N_tab[k]);
for (int n=0; n < polarParams->N; n++)
if (polarParams->G_N_tab[n])
free(polarParams->G_N_tab[n]);
free(polarParams->G_N_tab);
free(polarParams->rm_tab);
if (polarParams->crc_generator_matrix)
......@@ -71,6 +71,7 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
free(polarParams->deinterleaving_pattern);
free(polarParams->rate_matching_pattern);
free(polarParams->information_bit_pattern);
free(polarParams->parity_check_bit_pattern);
free(polarParams->Q_I_N);
free(polarParams->Q_F_N);
free(polarParams->Q_PC_N);
......@@ -234,6 +235,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->N,
newPolarInitNode->encoderLength);
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->parity_check_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
......@@ -242,14 +244,18 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->Q_F_N[i] = -1; // Empty array.
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
newPolarInitNode->parity_check_bit_pattern,
newPolarInitNode->Q_I_N,
newPolarInitNode->Q_F_N,
newPolarInitNode->Q_PC_N,
J,
newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength,
newPolarInitNode->n_pc);
newPolarInitNode->n_pc,
newPolarInitNode->n_pc_wm);
// sort the Q_I_N array in ascending order (first K positions)
qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
......
......@@ -49,6 +49,7 @@
#endif
//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
//#define POLAR_CODING_DEBUG
void nr_generate_pucch0(const PHY_VARS_NR_UE *ue,
c16_t **txdataF,
......@@ -693,7 +694,19 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
/*
* Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
*/
nr_pucch2_3_4_scrambling(M_bit,rnti,pucch_pdu->data_scrambling_id,&b[0],btilde);
nr_pucch2_3_4_scrambling(M_bit, rnti, pucch_pdu->data_scrambling_id, b, btilde);
#ifdef POLAR_CODING_DEBUG
printf("bt:");
for (int n = 0; n < M_bit; n++) {
if (n % 4 == 0) {
printf(" ");
}
printf("%u", btilde[n]);
}
printf("\n");
#endif
/*
* Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
* btilde shall be modulated as described in subclause 5.1 using QPSK
......
......@@ -1154,9 +1154,6 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
if(curr_pucch->csi_bits > 0 &&
!curr_pucch->simultaneous_harqcsi)
continue;
// TODO we can't schedule more than 11 bits in PUCCH2 for now
if (curr_pucch->csi_bits + curr_pucch->dai_c >= 10)
continue;
// otherwise we can schedule in this active PUCCH
// no need to check VRB occupation because already done when PUCCH has been activated
......
......@@ -850,7 +850,7 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR
pucchfmt2->interslotFrequencyHopping = NULL;
pucchfmt2->additionalDMRS = NULL;
pucchfmt2->maxCodeRate = calloc(1,sizeof(*pucchfmt2->maxCodeRate));
*pucchfmt2->maxCodeRate = NR_PUCCH_MaxCodeRate_zeroDot35;
*pucchfmt2->maxCodeRate = NR_PUCCH_MaxCodeRate_zeroDot15;
pucchfmt2->nrofSlots = NULL;
pucchfmt2->pi2BPSK = NULL;
......
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