Review soft demodulator zero check

This commit is contained in:
Xavier Arteaga 2021-04-12 11:23:27 +02:00 committed by Andre Puschmann
parent dd26c6a90e
commit b8a9a7fc70
4 changed files with 90 additions and 52 deletions

View File

@ -33,4 +33,14 @@ SRSRAN_API int srsran_demod_soft_demodulate_s(srsran_mod_t modulation, const cf_
SRSRAN_API int srsran_demod_soft_demodulate_b(srsran_mod_t modulation, const cf_t* symbols, int8_t* llr, int nsymbols); SRSRAN_API int srsran_demod_soft_demodulate_b(srsran_mod_t modulation, const cf_t* symbols, int8_t* llr, int nsymbols);
/**
* @brief Soft-demodulates complex symbols into 8-bit LLR. It forces zero symbols produce zero LLRs.
* @param modulation Modulation
* @param symbols Complex symbols
* @param llr 8-bit LLRs
* @param nsymbols Number of symbols
* @return SRSLTE_SUCCESS if the provided pointers are valid, SRSLTE_ERROR code otherwise
*/
SRSRAN_API int srsran_demod_soft_demodulate2_b(srsran_mod_t modulation, const cf_t* symbols, int8_t* llr, int nsymbols);
#endif // SRSRAN_DEMOD_SOFT_H #endif // SRSRAN_DEMOD_SOFT_H

View File

@ -883,6 +883,9 @@ int srsran_demod_soft_demodulate(srsran_mod_t modulation, const cf_t* symbols, f
int srsran_demod_soft_demodulate_s(srsran_mod_t modulation, const cf_t* symbols, short* llr, int nsymbols) int srsran_demod_soft_demodulate_s(srsran_mod_t modulation, const cf_t* symbols, short* llr, int nsymbols)
{ {
if (symbols == NULL || llr == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
switch (modulation) { switch (modulation) {
case SRSRAN_MOD_BPSK: case SRSRAN_MOD_BPSK:
demod_bpsk_lte_s(symbols, llr, nsymbols); demod_bpsk_lte_s(symbols, llr, nsymbols);
@ -908,6 +911,9 @@ int srsran_demod_soft_demodulate_s(srsran_mod_t modulation, const cf_t* symbols,
int srsran_demod_soft_demodulate_b(srsran_mod_t modulation, const cf_t* symbols, int8_t* llr, int nsymbols) int srsran_demod_soft_demodulate_b(srsran_mod_t modulation, const cf_t* symbols, int8_t* llr, int nsymbols)
{ {
if (symbols == NULL || llr == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
switch (modulation) { switch (modulation) {
case SRSRAN_MOD_BPSK: case SRSRAN_MOD_BPSK:
demod_bpsk_lte_b(symbols, llr, nsymbols); demod_bpsk_lte_b(symbols, llr, nsymbols);
@ -926,17 +932,34 @@ int srsran_demod_soft_demodulate_b(srsran_mod_t modulation, const cf_t* symbols,
break; break;
default: default:
ERROR("Invalid modulation %d", modulation); ERROR("Invalid modulation %d", modulation);
return -1; return SRSRAN_ERROR;
}
return SRSRAN_SUCCESS;
}
int srsran_demod_soft_demodulate2_b(srsran_mod_t modulation, const cf_t* symbols, int8_t* llr, int nsymbols)
{
if (symbols == NULL || llr == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
if (srsran_demod_soft_demodulate_b(modulation, symbols, llr, nsymbols) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
} }
// If the number of bits is 2 or less, this is unnecessary
if (modulation < SRSRAN_MOD_16QAM) {
return SRSRAN_SUCCESS;
}
// Iterate all symbols seeking for zero LLR
uint32_t nof_bits_x_symbol = srsran_mod_bits_x_symbol(modulation); uint32_t nof_bits_x_symbol = srsran_mod_bits_x_symbol(modulation);
for (uint32_t i = 0; i < nsymbols; i++) { for (uint32_t i = 0; i < nsymbols; i++) {
if (!isnormal(__real__ symbols[i]) || !isnormal(__imag__ symbols[i])) { if (symbols[i] == 0.0f) {
for (uint32_t j = 0; j < nof_bits_x_symbol; j++) { for (uint32_t j = 0; j < nof_bits_x_symbol; j++) {
llr[i * nof_bits_x_symbol + j] = 0; llr[i * nof_bits_x_symbol + j] = 0;
} }
} }
} }
return 0; return SRSRAN_SUCCESS;
} }

View File

@ -10,11 +10,8 @@
* *
*/ */
#include <math.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <strings.h> #include <strings.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
@ -25,7 +22,7 @@ static uint32_t nof_frames = 10;
static uint32_t num_bits = 1000; static uint32_t num_bits = 1000;
static srsran_mod_t modulation = SRSRAN_MOD_NITEMS; static srsran_mod_t modulation = SRSRAN_MOD_NITEMS;
void usage(char* prog) static void usage(char* prog)
{ {
printf("Usage: %s [nfv] -m modulation (1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64)\n", prog); printf("Usage: %s [nfv] -m modulation (1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64)\n", prog);
printf("\t-n num_bits [Default %d]\n", num_bits); printf("\t-n num_bits [Default %d]\n", num_bits);
@ -33,7 +30,7 @@ void usage(char* prog)
printf("\t-v srsran_verbose [Default None]\n"); printf("\t-v srsran_verbose [Default None]\n");
} }
void parse_args(int argc, char** argv) static void parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "nmvf")) != -1) { while ((opt = getopt(argc, argv, "nmvf")) != -1) {
@ -82,33 +79,16 @@ void parse_args(int argc, char** argv)
} }
} }
float mse_threshold()
{
switch (modulation) {
case SRSRAN_MOD_BPSK:
return 1.0e-6;
case SRSRAN_MOD_QPSK:
return 1.0e-6;
case SRSRAN_MOD_16QAM:
return 0.11;
case SRSRAN_MOD_64QAM:
return 0.19;
case SRSRAN_MOD_256QAM:
return 0.3;
default:
return -1.0f;
}
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int i;
srsran_modem_table_t mod; srsran_modem_table_t mod;
uint8_t * input, *output; uint8_t* input = NULL;
cf_t* symbols; cf_t* symbols = NULL;
float* llr; float* llr = NULL;
short* llr_s; short* llr_s = NULL;
int8_t* llr_b; int8_t* llr_b = NULL;
int8_t* llr_b2 = NULL;
srsran_random_t random_gen = srsran_random_init(0);
parse_args(argc, argv); parse_args(argc, argv);
@ -127,11 +107,6 @@ int main(int argc, char** argv)
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
output = srsran_vec_u8_malloc(num_bits);
if (!output) {
perror("malloc");
exit(-1);
}
symbols = srsran_vec_cf_malloc(num_bits / mod.nbits_x_symbol); symbols = srsran_vec_cf_malloc(num_bits / mod.nbits_x_symbol);
if (!symbols) { if (!symbols) {
perror("malloc"); perror("malloc");
@ -156,17 +131,21 @@ int main(int argc, char** argv)
exit(-1); exit(-1);
} }
/* generate random data */ llr_b2 = srsran_vec_i8_malloc(num_bits);
srand(0); if (!llr_b2) {
perror("malloc");
exit(-1);
}
int ret = -1; int ret = -1;
struct timeval t[3]; struct timeval t[3];
float mean_texec = 0.0; float mean_texec = 0.0f;
float mean_texec_s = 0.0; float mean_texec_s = 0.0f;
float mean_texec_b = 0.0; float mean_texec_b = 0.0f;
float mean_texec_b2 = 0.0f;
for (int n = 0; n < nof_frames; n++) { for (int n = 0; n < nof_frames; n++) {
for (i = 0; i < num_bits; i++) { for (int i = 0; i < num_bits; i++) {
input[i] = rand() % 2; input[i] = srsran_random_uniform_int_dist(random_gen, 0, 1);
} }
/* modulate */ /* modulate */
@ -200,6 +179,15 @@ int main(int argc, char** argv)
mean_texec_b = SRSRAN_VEC_CMA((float)t[0].tv_usec, mean_texec_b, n - 1); mean_texec_b = SRSRAN_VEC_CMA((float)t[0].tv_usec, mean_texec_b, n - 1);
} }
gettimeofday(&t[1], NULL);
srsran_demod_soft_demodulate2_b(modulation, symbols, llr_b2, num_bits / mod.nbits_x_symbol);
gettimeofday(&t[2], NULL);
get_time_interval(t);
if (n > 0) {
mean_texec_b2 = SRSRAN_VEC_CMA((float)t[0].tv_usec, mean_texec_b2, n - 1);
}
if (SRSRAN_VERBOSE_ISDEBUG()) { if (SRSRAN_VERBOSE_ISDEBUG()) {
printf("bits="); printf("bits=");
srsran_vec_fprint_b(stdout, input, num_bits); srsran_vec_fprint_b(stdout, input, num_bits);
@ -215,12 +203,27 @@ int main(int argc, char** argv)
printf("llr_b="); printf("llr_b=");
srsran_vec_fprint_bs(stdout, llr_b, num_bits); srsran_vec_fprint_bs(stdout, llr_b, num_bits);
printf("llr_b2=");
srsran_vec_fprint_bs(stdout, llr_b2, num_bits);
} }
// Check demodulation errors // Check demodulation errors
for (int i = 0; i < num_bits; i++) { for (int j = 0; j < num_bits; j++) {
if (input[i] != (llr[i] > 0 ? 1 : 0)) { if (input[j] != (llr[j] > 0 ? 1 : 0)) {
printf("Error in bit %d\n", i); ERROR("Error in bit %d\n", j);
goto clean_exit;
}
if (input[j] != (llr_s[j] > 0 ? 1 : 0)) {
ERROR("Error in bit %d\n", j);
goto clean_exit;
}
if (input[j] != (llr_b[j] > 0 ? 1 : 0)) {
ERROR("Error in bit %d\n", j);
goto clean_exit;
}
if (input[j] != (llr_b2[j] > 0 ? 1 : 0)) {
ERROR("Error in bit %d\n", j);
goto clean_exit; goto clean_exit;
} }
} }
@ -228,21 +231,23 @@ int main(int argc, char** argv)
ret = 0; ret = 0;
clean_exit: clean_exit:
srsran_random_free(random_gen);
free(llr_b); free(llr_b);
free(llr_s); free(llr_s);
free(llr); free(llr);
free(symbols); free(symbols);
free(output);
free(input); free(input);
srsran_modem_table_free(&mod); srsran_modem_table_free(&mod);
printf("Mean Throughput: %.2f/%.2f/%.2f. Mbps ExTime: %.2f/%.2f/%.2f us\n", printf("Mean Throughput: %.2f/%.2f/%.2f/%.2f. Mbps ExTime: %.2f/%.2f/%.2f/%.2f us\n",
num_bits / mean_texec, num_bits / mean_texec,
num_bits / mean_texec_s, num_bits / mean_texec_s,
num_bits / mean_texec_b, num_bits / mean_texec_b,
num_bits / mean_texec_b2,
mean_texec, mean_texec,
mean_texec_s, mean_texec_s,
mean_texec_b); mean_texec_b,
mean_texec_b2);
exit(ret); exit(ret);
} }

View File

@ -456,7 +456,7 @@ static inline int pdsch_nr_decode_codeword(srsran_pdsch_nr_t* q,
// Demodulation // Demodulation
int8_t* llr = (int8_t*)q->b[tb->cw_idx]; int8_t* llr = (int8_t*)q->b[tb->cw_idx];
if (srsran_demod_soft_demodulate_b(tb->mod, q->d[tb->cw_idx], llr, tb->nof_re)) { if (srsran_demod_soft_demodulate2_b(tb->mod, q->d[tb->cw_idx], llr, tb->nof_re)) {
return SRSRAN_ERROR; return SRSRAN_ERROR;
} }