16-bit integer optimization, reduced memcpy after list sorting
This commit is contained in:
@@ -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,12 +165,19 @@ 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);
|
||||
stop_meas(&timeDecoder);
|
||||
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
|
||||
if (decoderState==-1) {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -48,193 +48,499 @@ int8_t polar_decoder(
|
||||
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_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(double)*polarParams->N);
|
||||
}
|
||||
for (int j=0;j<polarParams->crcParityBits;j++) dlist[i].crcChecksum[j] = 0;
|
||||
dlist[i].crcState = 1;
|
||||
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);
|
||||
}
|
||||
|
||||
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_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(double)*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);
|
||||
|
||||
double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
|
||||
nr_polar_rate_matching(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(double)*polarParams->N);
|
||||
stop_meas(polar_rate_matching);
|
||||
|
||||
/*
|
||||
* SCL polar decoder.
|
||||
*/
|
||||
start_meas(decoding);
|
||||
uint32_t nonFrozenBit=0;
|
||||
uint8_t currentListSize=1;
|
||||
|
||||
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 (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);
|
||||
stop_meas(update_LLR);
|
||||
|
||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
||||
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) ) {
|
||||
//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;
|
||||
updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
||||
} else {
|
||||
|
||||
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));
|
||||
}
|
||||
start_meas(path_metric);
|
||||
updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr);
|
||||
stop_meas(path_metric);
|
||||
|
||||
start_meas(sorting);
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
|
||||
nr_polar_rate_matching(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(double)*polarParams->N);
|
||||
stop_meas(polar_rate_matching);
|
||||
|
||||
/*
|
||||
* SCL polar decoder.
|
||||
*/
|
||||
start_meas(decoding);
|
||||
uint32_t nonFrozenBit=0;
|
||||
uint8_t currentListSize=1;
|
||||
uint8_t copyIndex=0;
|
||||
|
||||
decoder_list_t *sorted_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);
|
||||
|
||||
start_meas(update_LLR);
|
||||
updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
||||
stop_meas(update_LLR);
|
||||
|
||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
||||
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]]);
|
||||
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++) {
|
||||
|
||||
//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".
|
||||
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;
|
||||
updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
||||
} else {
|
||||
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]->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] = 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;
|
||||
}
|
||||
|
||||
start_meas(path_metric);
|
||||
updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr);
|
||||
stop_meas(path_metric);
|
||||
|
||||
start_meas(sorting);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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 i = 0; i < currentListSize; i++) {
|
||||
sorted_dlist[i]->bit[0][currentBit]=0;
|
||||
sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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'
|
||||
|
||||
//Keep only the best "listSize" number of entries.
|
||||
if (currentListSize > listSize) {
|
||||
for (int i = 0; i < currentListSize; i++) {
|
||||
listIndex[i]=i;
|
||||
pathMetric[i] = dlist[i].pathMetric;
|
||||
}
|
||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
||||
currentListSize = listSize;
|
||||
for (uint8_t i = 0; i < 2*listSize; i++) {
|
||||
sorted_dlist[i] = &dlist[listIndex[i]];
|
||||
}
|
||||
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);
|
||||
}
|
||||
stop_meas(sorting);
|
||||
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));*/
|
||||
|
||||
}
|
||||
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]);
|
||||
// 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;
|
||||
|
||||
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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
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]);
|
||||
// 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]);
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -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]) ) ;
|
||||
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]) ) ;
|
||||
// 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)]);
|
||||
}
|
||||
} 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)]));
|
||||
}
|
||||
|
||||
free(tempPM);
|
||||
mask = dlist[i]->llr[0][row]>>15;
|
||||
|
||||
if (mask != 0) {
|
||||
int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask;
|
||||
dlist[i]->pathMetric += absllr;
|
||||
}
|
||||
// printf("updatepathmetric : llr %d, pathMetric %d (bitValue %d)\n",dlist[i]->llr[0][row],dlist[i]->pathMetric);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
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);
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user