Commit 8cda0a0f authored by Raymond Knopp's avatar Raymond Knopp

16-bit integer optimization, reduced memcpy after list sorting

parent 8b8e6e12
......@@ -18,6 +18,7 @@ int main(int argc, char *argv[]) {
time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
time_stats_t path_metric,sorting,update_LLR;
opp_enabled=1;
int decoder_int8=0;
cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
......@@ -30,7 +31,7 @@ int main(int argc, char *argv[]) {
reset_meas(&path_metric);
reset_meas(&update_LLR);
randominit(0);
randominit(1234);
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 1; //0=DCI, 1=PBCH, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
......@@ -43,7 +44,7 @@ int main(int argc, char *argv[]) {
uint8_t decoderListSize = 8, pathMetricAppr = 0; //0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h")) != -1)
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:q")) != -1)
switch (arguments)
{
case 's':
......@@ -75,6 +76,10 @@ int main(int argc, char *argv[]) {
pathMetricAppr = (uint8_t) atoi(optarg);
break;
case 'q':
decoder_int8=1;
break;
case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
exit(-1);
......@@ -131,6 +136,7 @@ int main(int argc, char *argv[]) {
double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input
double *channelOutput = malloc (sizeof(double) * coderLength); //add noise
int16_t *channelOutput_int8 = malloc (sizeof(int16_t) * coderLength); //add noise
uint8_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output
t_nrPolar_params nrPolar_params;
......@@ -159,11 +165,18 @@ int main(int argc, char *argv[]) {
modulatedInput[i]=(-1)/sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int8==1) {
if (channelOutput[i] > 1024) channelOutput_int8[i] = 32768;
else if (channelOutput[i] < -1023) channelOutput_int8[i] = -32767;
else channelOutput_int8[i] = (int16_t) (32*channelOutput[i]);
}
}
start_meas(&timeDecoder);
decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr,&polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR);
if (decoder_int8==0) decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr,&polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR);
else
decoderState = polar_decoder_int8(channelOutput_int8, estimatedOutput, &nrPolar_params, decoderListSize, &polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR);
stop_meas(&timeDecoder);
//calculate errors
......@@ -207,9 +220,9 @@ int main(int argc, char *argv[]) {
printf("decoding decoding %9.3fus\n",decoding.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding bit_extraction %9.3fus\n",bit_extraction.diff/(cpu_freq_GHz*1000.0*bit_extraction.trials));
printf("decoding deinterleaving %9.3fus\n",deinterleaving.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials));
printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials));
printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials));
printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials));
printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*decoding.trials));
blockErrorCumulative = 0; bitErrorCumulative = 0;
timeEncoderCumulative = 0; timeDecoderCumulative = 0;
}
......
......@@ -64,7 +64,6 @@ int8_t polar_decoder(
memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N);
}
for (int j=0;j<polarParams->crcParityBits;j++) dlist[i].crcChecksum[j] = 0;
dlist[i].crcState = 1;
dlist[i].pathMetric = 0;
}
......@@ -104,14 +103,6 @@ int8_t polar_decoder(
}
}
//The index of the last 1-valued bit that appears in each column.
uint16_t last1ind[polarParams->crcParityBits];
for (int j=0; j<polarParams->crcParityBits; j++) {
for (int i=0; i<polarParams->K; i++) {
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i;
}
}
stop_meas(init);
start_meas(polar_rate_matching);
......@@ -126,16 +117,17 @@ int8_t polar_decoder(
start_meas(decoding);
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
uint8_t copyIndex=0;
decoder_list_t *sorted_dlist[2*listSize];
decoder_list_t *temp_dlist[2*listSize];
int listIndex[2*listSize];
double pathMetric[2*listSize];
for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i];
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
// printf("***************** BIT %d\n",currentBit);
printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n",
currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]);
start_meas(update_LLR);
updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
......@@ -145,15 +137,12 @@ int8_t polar_decoder(
updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit],
polarParams->payloadBits,
aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]);
//Information bit with known value of "0".
updatePathMetric(sorted_dlist, currentListSize, 0, currentBit, pathMetricAppr);
bitUpdated[currentBit][0]=1; //0=False, 1=True
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
//Information bit with known value of "1".
printf("Information bit with known value of 1\n");
updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr);
for (uint8_t i=0; i<currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1;
bitUpdated[currentBit][0]=1;
......@@ -165,32 +154,97 @@ int8_t polar_decoder(
stop_meas(path_metric);
start_meas(sorting);
for (int i=0;i<currentListSize;i++) {
printf("sorted_dlist[%d] pathmetric %f\n",i,32*sorted_dlist[i]->pathMetric);
}
if (currentListSize <= listSize/2) {
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
for (int i = 0; i < currentListSize; i++) {
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N);
}
}
}
for (int i = 0; i < currentListSize; i++) {
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState;
sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;
}
for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
int listIndex2[listSize];
for (int i = 0; i < currentListSize; i++) {
listIndex[i]=i;
pathMetric[i] = dlist[i].pathMetric;
pathMetric[i] = sorted_dlist[i]->pathMetric;
}
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
for (int i=0;i<currentListSize;i++) {
listIndex2[listIndex[i]] = i;
}
// copy the llr/bit arrays that are needed
for (int i = 0; i < listSize; i++) {
printf("listIndex[%d] %d\n",i,listIndex[i]);
if ((listIndex2[i+listSize]<listSize) && (listIndex2[i]<listSize)) { // both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(double)*polarParams->N);
}
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
}
else if (listIndex2[i+listSize]<listSize) { // only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(double)*polarParams->N);
}
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
currentListSize = listSize;
for (uint8_t i = 0; i < 2*listSize; i++) {
sorted_dlist[i] = &dlist[listIndex[i]];
for (int i = 0; i < 2*listSize; i++) {
temp_dlist[i] = sorted_dlist[i];
}
for (int i = 0; i < 2*listSize; i++) {
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist[i] = temp_dlist[listIndex[i]];
}
}
stop_meas(sorting);
......@@ -201,6 +255,258 @@ int8_t polar_decoder(
}
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
// printf("list index %d :",i);
// for (int j=0;j<polarParams->crcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]);
// printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric);
int crcState = 1;
for (int j=0;j<polarParams->crcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0;
if (crcState == 1) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j];
start_meas(bit_extraction);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
stop_meas(bit_extraction);
//Deinterleaving (ĉ to b)
start_meas(deinterleaving);
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
stop_meas(deinterleaving);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
break;
}
}
// free(d_tilde);
/*
for (int i=0;i<2*listSize;i++) {
// printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit);
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
free(dlist[i].crcChecksum);
}*/
nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_t_2D_array(tempECGM, polarParams->K);
stop_meas(decoding);
return(0);
}
int8_t polar_decoder_int8(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR)
{
start_meas(init);
uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
decoder_list_int8_t dlist[2*listSize];
for ( int i=0;i<2*listSize;i++) {
// dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
// dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N);
//dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits);
for (int j=0; j< polarParams->n+1; j++) {
memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N);
memset((void*)&dlist[i].llr[j][0],0,sizeof(int16_t)*polarParams->N);
}
for (int j=0;j<polarParams->crcParityBits;j++) dlist[i].crcChecksum[j] = 0;
dlist[i].pathMetric = 0;
}
for (int i=0; i<polarParams->N; i++) {
memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
for (int i = 0; i < polarParams->K; i++){
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
}
}
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
if( (i-polarParams->payloadBits) == j ){
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
}
}
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
}
}
stop_meas(init);
start_meas(polar_rate_matching);
int16_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);
memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N);
stop_meas(polar_rate_matching);
/*
* SCL polar decoder.
*/
start_meas(decoding);
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
decoder_list_int8_t *sorted_dlist[2*listSize];
decoder_list_int8_t *temp_dlist[2*listSize];
int listIndex[2*listSize];
int32_t pathMetric[2*listSize];
for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i];
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
// printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n",
// currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]);
start_meas(update_LLR);
updateLLR_int8(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1));
stop_meas(update_LLR);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
start_meas(path_metric);
updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit);
stop_meas(path_metric);
start_meas(sorting);
// for (int i=0;i<currentListSize;i++) {
// printf("sorted_dlist[%d] pathmetric %d\n",i,sorted_dlist[i]->pathMetric);
// }
if (currentListSize <= listSize/2) {
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
for (int i = 0; i < currentListSize; i++) {
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
}
}
for (int i = 0; i < currentListSize; i++) {
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;
}
bitUpdated[currentBit][0]=1;
updateCrcChecksum2_int8(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
int listIndex2[listSize];
for (int i = 0; i < currentListSize; i++) {
listIndex[i]=i;
pathMetric[i] = sorted_dlist[i]->pathMetric;
}
nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize);
for (int i=0;i<currentListSize;i++) {
listIndex2[listIndex[i]] = i;
}
// copy the llr/bit arrays that are needed
for (int i = 0; i < listSize; i++) {
// printf("listIndex[%d] %d\n",i,listIndex[i]);
if ((listIndex2[i+listSize]<listSize) && (listIndex2[i]<listSize)) { // both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
}
else if (listIndex2[i+listSize]<listSize) { // only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
currentListSize = listSize;
for (int i = 0; i < 2*listSize; i++) {
temp_dlist[i] = sorted_dlist[i];
}
for (int i = 0; i < 2*listSize; i++) {
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist[i] = temp_dlist[listIndex[i]];
}
}
stop_meas(sorting);
nonFrozenBit++;
}
}
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
// printf("list index %d :",i);
// for (int j=0;j<polarParams->crcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]);
......
......@@ -33,7 +33,7 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
#ifdef SHOWCOMP
printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i);
printf("computeLLR (%d,%d,%d)\n",row,col,offset);
#endif
a = llr[col + 1][row];
b = llr[col+1][row + offset];
......@@ -45,6 +45,37 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
} else { //eq. (8a)
llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col,
uint16_t offset) __attribute__((always_inline));
inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col,
uint16_t offset) {
int16_t a;
int16_t b;
int16_t absA,absB;
int16_t maska,maskb;
int16_t minabs;
#ifdef SHOWCOMP
printf("computeLLR_int8 (%d,%d,%d)\n",row,col,offset);
#endif
a = llr[col + 1][row];
b = llr[col+1][row + offset];
// printf("LLR: a %d, b %d\n",a,b);
maska = a>>15;
maskb = b>>15;
absA = (a+maska)^maska;
absB = (b+maskb)^maskb;
// printf("LLR: absA %d, absB %d\n",absA,absB);
minabs = absA<absB ? absA : absB;
if ((maska^maskb) == 0)
llr[col][row] = minabs;
else
llr[col][row] = -minabs;
// printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]);
}
......@@ -56,19 +87,46 @@ void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
for (uint8_t i=0; i<listSize; i++) {
#ifdef SHOWCOMP
printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i,
printf("updatingLLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i,
row-offset,col,i,row-offset,col+1,i,row,col+1,i);
#endif
dlist[i]->llr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row];
// printf("updating dlist[%d]->llr[%d][%d] => %f (%f,%f) offset %d\n",i,col,row,32*dlist[i]->llr[col][row],
// (pow((-1),dlist[i]->bit[col][row-offset])*32*dlist[i]->llr[col+1][row-offset]),32*dlist[i]->llr[col+1][row],offset);
}
} else {
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
for (int i=0;i<listSize;i++) computeLLR(dlist[i]->llr, row, col, offset, approximation);
}
llrU[row][col]=1;
}
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen) {
uint16_t offset = (xlen/(1<<(ylen-col-1)));
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen);
if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen);
if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen);
for (uint8_t i=0; i<listSize; i++) {
#ifdef SHOWCOMP
printf("updatingLLR_int8 (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i,
row-offset,col,i,row-offset,col+1,i,row,col+1,i);
#endif
if (dlist[i]->bit[col][row-offset]==0)
dlist[i]->llr[col][row] = dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];
else
dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];
// printf("updating dlist[%d]->llr[%d][%d] => %d (%d,%d) offset %d\n",i,col,row,dlist[i]->llr[col][row],
// (dlist[i]->bit[col][row-offset]==0 ? 1 : -1)*dlist[i]->llr[col+1][row-offset],dlist[i]->llr[col+1][row], offset);
}
} else {
if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen);
if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen);
for (int i=0;i<listSize;i++) computeLLR_int8(dlist[i]->llr, row, col, offset);
}
llrU[row][col]=1;
......@@ -90,6 +148,34 @@ void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2);
// printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]);
#ifdef SHOWCOMP
printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n",
row,col,i,row,col-1,i,row+offset,col-1,i);
#endif
}
}
bitU[row][col]=1;
}
void updateBit_int8(decoder_list_int8_t **dlist, 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))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen);
dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
#ifdef SHOWCOMP
printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n",
row,col,i,row,col-1,i);
#endif
} else {
if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset];
// printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]);
#ifdef SHOWCOMP
printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n",
row,col,i,row,col-1,i,row+offset,col-1,i);
......@@ -111,44 +197,42 @@ void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,dlist[i]->llr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]);
// printf("updatepathmetric : llr %f pathMetric %f (bitValue %d)\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric,bitValue);
}
} else { //eq. (11b)
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) dlist[i]->pathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ;
for (uint8_t i=0; i<listSize; i++) {
dlist[i]->pathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ;
// printf("updatepathmetric : llr %f pathMetric %f\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric);
}
}
}
/*
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint16_t row, uint8_t appr) {
double *tempPM = malloc(sizeof(double) * listSize);
for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i];
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row) {
uint8_t bitValue = 0;
if (appr) { //eq. (12)
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]);
}
} else { //eq. (11b)
int8_t multiplier = (2 * bitValue) - 1;
for (uint8_t i = 0; i < listSize; i++) pathMetric[i] += log(1 + exp(multiplier * llr[row][0][i]));
}
#ifdef SHOWCOMP
printf("updating path_metric from Frozen bit (%d,%d) \n",
row,0);
#endif
int16_t mask;
for (uint8_t i=0; i<listSize; i++) {
// if ((2*bitValue) != ( 1 - copysign(1.0,dlist[i]->llr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]);
// equiv: if ((llr>0 && bitValue==1) || (llr<0 && bitValue==0) ...
// equiv: (llr>>7 + bitValue) != 0, in opposite case (llr>8 + bitValue) = -1 or 1
bitValue = 1;
if (appr) { //eq. (12)
for (uint8_t i = listSize; i < 2*listSize; i++) {
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][(i-listSize)]))) pathMetric[i] = tempPM[(i-listSize)] + fabs(llr[row][0][(i-listSize)]);
mask = dlist[i]->llr[0][row]>>15;
if (mask != 0) {
int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask;
dlist[i]->pathMetric += absllr;
}
} else { //eq. (11b)
int8_t multiplier = (2 * bitValue) - 1;
for (uint8_t i = listSize; i < 2*listSize; i++) pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)]));
// printf("updatepathmetric : llr %d, pathMetric %d (bitValue %d)\n",dlist[i]->llr[0][row],dlist[i]->pathMetric);
}
free(tempPM);
}
*/
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) {
......@@ -174,10 +258,29 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u
dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row]));
// bitValue=1
dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row]));
}
}
}
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row) {
int i;
for (i=0;i<listSize;i++) dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
decoder_list_int8_t **dlist2 = &dlist[listSize];
#ifdef SHOWCOMP
printf("updating path_metric from information bit (%d,%d) \n",
row,0);
#endif
for (i = 0; i < listSize; i++) {
// bitValue=0
if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
// bitValue=1
else dlist2[i]->pathMetric += dlist[i]->llr[0][row];
}
}
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
......@@ -197,3 +300,21 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
}
}
}
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
......@@ -104,6 +104,9 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P
void nr_polar_rate_matching(double *input, double *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);
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, int16_t *Q_I_N, int16_t *Q_F_N,
......@@ -138,31 +141,57 @@ typedef struct decoder_list_s {
uint8_t bit[1+nmax][Nmax];
double llr[1+nmax][Nmax];
uint8_t crcChecksum[24];
uint8_t crcState;
double pathMetric;
} decoder_list_t;
typedef struct decoder_list_int8_s {
uint8_t bit[1+nmax][Nmax];
int16_t llr[1+nmax][Nmax];
uint8_t crcChecksum[24];
int32_t pathMetric;
} decoder_list_int8_t;
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation);
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen);
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation);
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row);
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr);
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row);
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len);
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
......
......@@ -168,3 +168,28 @@ void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) {
break;
}
}
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len) {
int swaps;
int16_t temp;
int tempInd;
for (int i = 0; i < len; i++) {
swaps = 0;
for (int j = 0; j < (len - i) - 1; j++) {
if (matrix[j] > matrix[j + 1]) {
temp = matrix[j];
matrix[j] = matrix[j + 1];
matrix[j + 1] = temp;
tempInd = ind[j];
ind[j] = ind[j + 1];
ind[j + 1] = tempInd;
swaps++;
}
}
if (swaps == 0)
break;
}
}
......@@ -79,3 +79,24 @@ 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){
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];
}
}
}
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