|
|
@ -10,8 +10,11 @@
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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>
|
|
|
@ -22,7 +25,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;
|
|
|
|
|
|
|
|
|
|
|
|
static void usage(char* prog)
|
|
|
|
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);
|
|
|
@ -30,7 +33,7 @@ static void usage(char* prog)
|
|
|
|
printf("\t-v srsran_verbose [Default None]\n");
|
|
|
|
printf("\t-v srsran_verbose [Default None]\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void parse_args(int argc, char** argv)
|
|
|
|
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) {
|
|
|
@ -79,16 +82,33 @@ static 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 = NULL;
|
|
|
|
uint8_t * input, *output;
|
|
|
|
cf_t* symbols = NULL;
|
|
|
|
cf_t* symbols;
|
|
|
|
float* llr = NULL;
|
|
|
|
float* llr;
|
|
|
|
short* llr_s = NULL;
|
|
|
|
short* llr_s;
|
|
|
|
int8_t* llr_b = NULL;
|
|
|
|
int8_t* llr_b;
|
|
|
|
int8_t* llr_b2 = NULL;
|
|
|
|
|
|
|
|
srsran_random_t random_gen = srsran_random_init(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parse_args(argc, argv);
|
|
|
|
parse_args(argc, argv);
|
|
|
|
|
|
|
|
|
|
|
@ -107,6 +127,11 @@ 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");
|
|
|
@ -131,21 +156,17 @@ int main(int argc, char** argv)
|
|
|
|
exit(-1);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
llr_b2 = srsran_vec_i8_malloc(num_bits);
|
|
|
|
/* generate random data */
|
|
|
|
if (!llr_b2) {
|
|
|
|
srand(0);
|
|
|
|
perror("malloc");
|
|
|
|
|
|
|
|
exit(-1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ret = -1;
|
|
|
|
int ret = -1;
|
|
|
|
struct timeval t[3];
|
|
|
|
struct timeval t[3];
|
|
|
|
float mean_texec = 0.0f;
|
|
|
|
float mean_texec = 0.0;
|
|
|
|
float mean_texec_s = 0.0f;
|
|
|
|
float mean_texec_s = 0.0;
|
|
|
|
float mean_texec_b = 0.0f;
|
|
|
|
float mean_texec_b = 0.0;
|
|
|
|
float mean_texec_b2 = 0.0f;
|
|
|
|
|
|
|
|
for (int n = 0; n < nof_frames; n++) {
|
|
|
|
for (int n = 0; n < nof_frames; n++) {
|
|
|
|
for (int i = 0; i < num_bits; i++) {
|
|
|
|
for (i = 0; i < num_bits; i++) {
|
|
|
|
input[i] = srsran_random_uniform_int_dist(random_gen, 0, 1);
|
|
|
|
input[i] = rand() % 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* modulate */
|
|
|
|
/* modulate */
|
|
|
@ -179,15 +200,6 @@ 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);
|
|
|
@ -203,27 +215,12 @@ 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 j = 0; j < num_bits; j++) {
|
|
|
|
for (int i = 0; i < num_bits; i++) {
|
|
|
|
if (input[j] != (llr[j] > 0 ? 1 : 0)) {
|
|
|
|
if (input[i] != (llr[i] > 0 ? 1 : 0)) {
|
|
|
|
ERROR("Error in bit %d\n", j);
|
|
|
|
printf("Error in bit %d\n", i);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -231,23 +228,21 @@ 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/%.2f. Mbps ExTime: %.2f/%.2f/%.2f/%.2f us\n",
|
|
|
|
printf("Mean Throughput: %.2f/%.2f/%.2f. Mbps ExTime: %.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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|