From 24466fd2426c7c9eea43ce43d1e378ad05d92063 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Sun, 12 Apr 2020 19:55:25 +0200 Subject: [PATCH] Added PR sequence unit test/benchmark --- lib/src/phy/common/CMakeLists.txt | 2 + lib/src/phy/common/test/CMakeLists.txt | 28 +++++ lib/src/phy/common/test/sequence_test.c | 130 ++++++++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 lib/src/phy/common/test/CMakeLists.txt create mode 100644 lib/src/phy/common/test/sequence_test.c diff --git a/lib/src/phy/common/CMakeLists.txt b/lib/src/phy/common/CMakeLists.txt index 21beb92ca..53726c931 100644 --- a/lib/src/phy/common/CMakeLists.txt +++ b/lib/src/phy/common/CMakeLists.txt @@ -20,3 +20,5 @@ set(SOURCES phy_common.c phy_common_sl.c sequence.c timestamp.c) add_library(srslte_phy_common OBJECT ${SOURCES}) + +add_subdirectory(test) \ No newline at end of file diff --git a/lib/src/phy/common/test/CMakeLists.txt b/lib/src/phy/common/test/CMakeLists.txt new file mode 100644 index 000000000..800af8c8a --- /dev/null +++ b/lib/src/phy/common/test/CMakeLists.txt @@ -0,0 +1,28 @@ +# +# Copyright 2013-2020 Software Radio Systems Limited +# +# This file is part of srsLTE +# +# srsLTE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# srsLTE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# A copy of the GNU Affero General Public License can be found in +# the LICENSE file in the top-level directory of this distribution +# and at http://www.gnu.org/licenses/. +# + +######################################################################## +# SEQUENCE TEST +######################################################################## + +add_executable(sequence_test sequence_test.c) +target_link_libraries(sequence_test srslte_phy) + +add_test(sequence_test sequence_test) diff --git a/lib/src/phy/common/test/sequence_test.c b/lib/src/phy/common/test/sequence_test.c new file mode 100644 index 000000000..311c8794d --- /dev/null +++ b/lib/src/phy/common/test/sequence_test.c @@ -0,0 +1,130 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include "srslte/phy/utils/debug.h" +#include +#include +#include + +#define Nc 1600 +#define MAX_SEQ_LEN (256 * 1024) + +static uint8_t x1[Nc + MAX_SEQ_LEN + 31]; +static uint8_t x2[Nc + MAX_SEQ_LEN + 31]; +static uint8_t c[Nc + MAX_SEQ_LEN + 31]; +static float c_float[Nc + MAX_SEQ_LEN + 31]; +static int16_t c_short[Nc + MAX_SEQ_LEN + 31]; +static int8_t c_char[Nc + MAX_SEQ_LEN + 31]; +static uint8_t c_packed[MAX_SEQ_LEN / 8]; + +static int test_sequence(srslte_sequence_t* sequence, uint32_t seed, uint32_t length, uint32_t repetitions) +{ + int ret = SRSLTE_SUCCESS; + struct timeval t[3] = {}; + gettimeofday(&t[1], NULL); + + // Generate sequence + for (uint32_t r = 0; r < repetitions; r++) { + srslte_sequence_LTE_pr(sequence, length, seed); + } + + gettimeofday(&t[2], NULL); + get_time_interval(t); + + // Generate gold sequence + for (uint32_t n = 0; n < 31; n++) { + x2[n] = (seed >> n) & 0x1; + } + x1[0] = 1; + + for (uint32_t n = 0; n < Nc + length; n++) { + x1[n + 31] = (x1[n + 3] + x1[n]) & 0x1; + x2[n + 31] = (x2[n + 3] + x2[n + 2] + x2[n + 1] + x2[n]) & 0x1; + } + + for (uint32_t n = 0; n < length; n++) { + c[n] = (x1[n + Nc] + x2[n + Nc]) & 0x1; + c_float[n] = c[n] ? -1.0f : +1.0f; + c_short[n] = c[n] ? -1 : +1; + c_char[n] = c[n] ? -1 : +1; + } + + srslte_bit_pack_vector(c, c_packed, length); + + if (memcmp(c, sequence->c, length) != 0) { + ERROR("Unmatched c\n"); + ret = SRSLTE_ERROR; + } + + if (memcmp(c_float, sequence->c_float, length * sizeof(float)) != 0) { + ERROR("Unmatched c_float\n"); + ret = SRSLTE_ERROR; + } + + if (memcmp(c_short, sequence->c_short, length * sizeof(int16_t)) != 0) { + ERROR("Unmatched c_short\n"); + ret = SRSLTE_ERROR; + } + + if (memcmp(c_char, sequence->c_char, length * sizeof(int8_t)) != 0) { + ERROR("Unmatched c_char\n"); + ret = SRSLTE_ERROR; + } + + if (memcmp(c_packed, sequence->c_bytes, length / 8) != 0) { + ERROR("Unmatched c_packed\n"); + ret = SRSLTE_ERROR; + } + + uint64_t elapsed_us = t->tv_usec + t->tv_sec * 1000000UL; + printf("%08x; %8d; %8.1f; %8c\n", + seed, + length, + (double)(length * repetitions) / (double)elapsed_us, + ret == SRSLTE_SUCCESS ? 'y' : 'n'); + + return SRSLTE_SUCCESS; +} + +int main(int argc, char** argv) +{ + uint32_t repetitions = 1; + uint32_t min_length = 16; + uint32_t max_length = MAX_SEQ_LEN; + + srslte_sequence_t sequence = {}; + srslte_random_t random_gen = srslte_random_init(0); + + // Initialise sequence object + srslte_sequence_init(&sequence, max_length); + + printf("%8s; %8s; %8s; %8s\n", "seed", "length", "Rate M/s", "Passed"); + + for (uint32_t length = min_length; length <= max_length; length = (length * 5) / 4) { + test_sequence(&sequence, (uint32_t)srslte_random_uniform_int_dist(random_gen, 1, INT32_MAX), length, repetitions); + } + + // Free sequence object + srslte_sequence_free(&sequence); + srslte_random_free(random_gen); + + return SRSLTE_SUCCESS; +} \ No newline at end of file