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
No related merge requests found
......@@ -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