Commit a3f8cb99 authored by rickyskv's avatar rickyskv

polar decoder 8 bits

solved problems with the structure
generated testbench option
it runs, time decreases increasing SNR but same BLER
is it counting correctly the BLER?
parent 4016a10d
......@@ -26,6 +26,7 @@ int main(int argc, char *argv[])
{
//Default simulation values (Aim for iterations = 1000000.)
int decoder_int16=0;
int16_t decoder_int8=0;
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
double SNR, SNR_lin;
......@@ -37,7 +38,7 @@ int main(int argc, char *argv[])
uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0;
uint16_t rnti=0;
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:p:hqgFL:k:")) != -1)
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:p:q:hgFL:k:")) != -1)
switch (arguments) {
case 's':
SNRstart = atof(optarg);
......@@ -68,6 +69,13 @@ int main(int argc, char *argv[])
case 'q':
decoder_int16 = 1;
decoder_int8=atoi(optarg);
if (decoder_int8 != 8 && decoder_int8 != 1 && decoder_int8 != 0 && decoder_int8 != 16) {
printf("Illegal argument for option -q: %d \nPossible values: 0 or 16 to use 16-bit decoder, 1 or 8 to use the 8-bit decoder\n",decoder_int8);
exit(-1);
}
if (decoder_int8 == 8) decoder_int8=1;
if (decoder_int8 == 16) decoder_int8=0;
break;
case 'g':
......@@ -99,7 +107,7 @@ int main(int argc, char *argv[])
case 'h':
printf("./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage [0 = 16-bit, 1 = 8-bit]\n-F Flag for test results logging\n"
"-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
exit(-1);
break;
......@@ -175,8 +183,9 @@ if (logFlag){
double modulatedInput[coderLength]; //channel input
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
int8_t channelOutput_int8[coderLength];
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, 1, NULL);
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, decoder_int8+1, NULL);
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
......@@ -272,16 +281,28 @@ if (logFlag){
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int16==1) {
if(decoder_int8==0){
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
else{
if (channelOutput[i] > 15) channelOutput_int8[i] = 63;
else if (channelOutput[i] < -16) channelOutput_int8[i] = -64;
else channelOutput_int8[i] = (int8_t) (4*channelOutput[i]);
}
}
}
start_meas(&timeDecoder);
if (decoder_int16==1) {
if(decoder_int8==0){
decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, currentPtr);
}
else{
decoderState = polar_decoder_int8(channelOutput_int8, (uint64_t *)estimatedOutput, 0, currentPtr);
}
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) {
decoderState = polar_decoder(channelOutput,
......
......@@ -708,20 +708,18 @@ uint32_t polar_decoder_int16(int16_t *input,
// ############### INT 8 #########################
uint32_t polar_decoder_int8(int16_t *input,
uint32_t polar_decoder_int8(int8_t *input,
uint64_t *out,
uint8_t ones_flag,
const t_nrPolar_params *polarParams)
{
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);
int8_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
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);
memcpy((void *)&polarParams->tree.root->alpha8[0],(void *)&d_tilde[0],sizeof(int8_t)*polarParams->N);
generic_polar_decoder_int8(polarParams,polarParams->tree.root);
//Extract the information bits (û to ĉ)
uint64_t Cprime[4]= {0,0,0,0};
......
......@@ -518,9 +518,9 @@ decoder_node_t *new_decoder_node_int8(int first_leaf_index, int level) {
node->left=(decoder_node_t *)NULL;
node->right=(decoder_node_t *)NULL;
node->all_frozen=0;
node->alpha = (int8_t*)malloc16(node->Nv*sizeof(int8_t));
node->beta = (int8_t*)malloc16(node->Nv*sizeof(int8_t));
memset((void*)node->beta,-1,node->Nv*sizeof(int8_t));
node->alpha8 = (int8_t*)malloc16(node->Nv*sizeof(int8_t));
node->beta8 = (int8_t*)malloc16(node->Nv*sizeof(int8_t));
memset((void*)node->beta8,-1,node->Nv*sizeof(int8_t));
return(node);
}
......@@ -589,9 +589,9 @@ void build_decoder_tree_int8(t_nrPolar_params *polarParams)
#endif
void applyFtoleft_int8(const t_nrPolar_params *pp, decoder_node_t *node) {
int8_t *alpha_v=node->alpha;
int8_t *alpha_l=node->left->alpha;
int8_t *betal = node->left->beta;
int8_t *alpha_v=node->alpha8;
int8_t *alpha_l=node->left->alpha8;
int8_t *betal = node->left->beta8;
int8_t a,b,absa,absb,maska,maskb,minabs;
#ifdef DEBUG_NEW_IMPL
......@@ -635,7 +635,7 @@ void applyFtoleft_int8(const t_nrPolar_params *pp, decoder_node_t *node) {
b64 =((__m64*)alpha_v)[1];
absa64 =_mm_abs_pi8(a64);
absb64 =_mm_abs_pi8(b64);
minabs64 =_mm_min_pi8(absa64,absb64);
minabs64 =_mm_min_pu8(absa64,absb64);
*((__m64*)alpha_l) =_mm_sign_pi8(minabs64,_mm_sign_pi8(a64,b64));
}
else
......@@ -663,7 +663,7 @@ void applyFtoleft_int8(const t_nrPolar_params *pp, decoder_node_t *node) {
b64 =((__m64*)alpha_v)[1];
absa64 =_mm_abs_pi8(a64);
absb64 =_mm_abs_pi8(b64);
minabs64 =_mm_min_pi8(absa64,absb64);
minabs64 =_mm_min_pu8(absa64,absb64);
*((__m64*)alpha_l) =_mm_sign_pi8(minabs64,_mm_sign_epi8(a64,b64));
}
......@@ -697,10 +697,10 @@ void applyFtoleft_int8(const t_nrPolar_params *pp, decoder_node_t *node) {
void applyGtoright_int8(const t_nrPolar_params *pp,decoder_node_t *node) {
int8_t *alpha_v=node->alpha;
int8_t *alpha_r=node->right->alpha;
int8_t *betal = node->left->beta;
int8_t *betar = node->right->beta;
int8_t *alpha_v=node->alpha8;
int8_t *alpha_r=node->right->alpha8;
int8_t *betal = node->left->beta8;
int8_t *betar = node->right->beta8;
#ifdef DEBUG_NEW_IMPL
printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",node->first_leaf_index,node->Nv,node->level,node->right->leaf,node->right->all_frozen);
......@@ -713,10 +713,7 @@ void applyGtoright_int8(const t_nrPolar_params *pp,decoder_node_t *node) {
int avx2len = node->Nv/2/32;
for (int i=0;i<avx2len;i++) {
((__m256i *)alpha_r)[i] =
_mm256_subs_epi8(((__m256i *)alpha_v)[i+avx2len],
_mm256_sign_epi8(((__m256i *)alpha_v)[i],
((__m256i *)betal)[i]));
((__m256i *)alpha_r)[i] = _mm256_subs_epi8(((__m256i *)alpha_v)[i+avx2len], _mm256_sign_epi8(((__m256i *)alpha_v)[i], ((__m256i *)betal)[i]));
}
}
else if (avx2mod == 16) {
......@@ -757,20 +754,20 @@ void applyGtoright_int8(const t_nrPolar_params *pp,decoder_node_t *node) {
}
}
int8_t all1[8] = {1,1,1,1,1,1,1,1};
int8_t all1_int8[8] = {1,1,1,1,1,1,1,1};
void computeBeta_int8(const t_nrPolar_params *pp,decoder_node_t *node) {
int8_t *betav = node->beta;
int8_t *betal = node->left->beta;
int8_t *betar = node->right->beta;
int8_t *betav = node->beta8;
int8_t *betal = node->left->beta8;
int8_t *betar = node->right->beta8;
#ifdef DEBUG_NEW_IMPL
printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen);
#endif
if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits
#if defined(__AVX2__)
int avx2mod = (node->Nv/2)&31;
register __m256i allones=*((__m256i*)all1);
register __m256i allones=*((__m256i*)all1_int8);
if (avx2mod == 0) {
int avx2len = node->Nv/2/32;
for (int i=0;i<avx2len;i++) {
......@@ -780,11 +777,11 @@ void computeBeta_int8(const t_nrPolar_params *pp,decoder_node_t *node) {
}
else if (avx2mod == 16) {
((__m128i*)betav)[0] = _mm_or_si128(_mm_cmpeq_epi8(((__m128i*)betar)[0],
((__m128i*)betal)[0]),*((__m128i*)all1));
((__m128i*)betal)[0]),*((__m128i*)all1_int8));
}
else if (avx2mod == 8) {
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi8(((__m64*)betar)[0],
((__m64*)betal)[0]),*((__m64*)all1));
((__m64*)betal)[0]),*((__m64*)all1_int8));
}
else
#else
......@@ -792,13 +789,13 @@ void computeBeta_int8(const t_nrPolar_params *pp,decoder_node_t *node) {
int ssr4mod = (node->Nv/2)&15;
if (ssr4mod == 0) {
int ssr4len = node->Nv/2/16;
register __m128i allones=*((__m128i*)all1);
register __m128i allones=*((__m128i*)all1_int8);
for (int i=0;i<sse4len;i++) {
((__m128i*)betav)[i] = _mm_or_si128(_mm_cmpeq_epi8(((__m128i*)betar)[i], ((__m128i*)betal)[i]),allones);
}
}
else if (sse4mod == 8) {
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi8(((__m64*)betar)[0], ((__m64*)betal)[0]),*((__m64*)all1));
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi8(((__m64*)betar)[0], ((__m64*)betal)[0]),*((__m64*)all1_int8));
}
else
#endif
......@@ -817,11 +814,12 @@ void generic_polar_decoder_int8(const t_nrPolar_params *pp,decoder_node_t *node)
// Apply F to left
applyFtoleft_int8(pp, node);
// if left is not a leaf recurse down to the left
if (node->left->leaf==0)
generic_polar_decoder_int8(pp, node->left);
applyGtoright(pp, node);
applyGtoright_int8(pp, node);
if (node->right->leaf==0) generic_polar_decoder_int8(pp, node->right);
computeBeta_int8(pp, node);
......
......@@ -70,6 +70,8 @@ typedef struct decoder_node_t_s {
int all_frozen;
int16_t *alpha;
int16_t *beta;
int8_t *alpha8;
int8_t *beta8;
} decoder_node_t;
typedef struct decoder_tree_t_s {
......@@ -161,6 +163,14 @@ uint32_t polar_decoder_int16(int16_t *input,
uint8_t ones_flag,
const t_nrPolar_params *polarParams);
// ############## INT 8 ##############
uint32_t polar_decoder_int8(int8_t *input,
uint64_t *out,
uint8_t ones_flag,
const t_nrPolar_params *polarParams);
//################ END INT 8 ################
int8_t polar_decoder_dci(double *input,
uint32_t *out,
t_nrPolar_params *polarParams,
......@@ -180,6 +190,25 @@ void computeBeta(const t_nrPolar_params *pp,
decoder_node_t *node);
void build_decoder_tree(t_nrPolar_params *pp);
//################ INT 8 ##############
void generic_polar_decoder_int8(const t_nrPolar_params *pp,
decoder_node_t *node);
void applyFtoleft_int8(const t_nrPolar_params *pp,
decoder_node_t *node);
void applyGtoright_int8(const t_nrPolar_params *pp,
decoder_node_t *node);
void computeBeta_int8(const t_nrPolar_params *pp,
decoder_node_t *node);
void build_decoder_tree_int8(t_nrPolar_params *pp);
//################ END INT 8 ################
void build_polar_tables(t_nrPolar_params *polarParams);
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams);
......@@ -231,6 +260,15 @@ void nr_polar_rate_matching_int16(int16_t *input,
uint16_t N,
uint16_t E);
//########### INT 8 ################
void nr_polar_rate_matching_int8(int8_t *input,
int8_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
//########### END INT 8 ################
void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL,
uint16_t *PI_k_);
......
......@@ -345,3 +345,24 @@ void nr_polar_rate_matching_int16(int16_t *input,
}
}
void nr_polar_rate_matching_int8(int8_t *input,
int8_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
{
if (E>=N) { //repetition
memset((void*)output,0,N*sizeof(int8_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(int8_t)); //puncturing
else { //shortening
for (int i=0; i<=N-1; i++) output[i]=127;//instead of INFINITY, to prevent [-Woverflow]
}
for (int i=0; i<=E-1; i++) output[rmp[i]]=input[i];
}
}
......@@ -80,7 +80,7 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16
}
void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
/*void nr_polar_rate_matching_int8(int16_t *input, int16_t *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;
......@@ -99,4 +99,4 @@ void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp,
}
}
}
}*/
......@@ -183,6 +183,7 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
newPolarInitNode->encoderLength);
free(J);
if (decoder_flag == 1) build_decoder_tree(newPolarInitNode);
if (decoder_flag == 2) build_decoder_tree_int8(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
......
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