diff --git a/CMakeLists.txt b/CMakeLists.txt index 89c5bb254..e3d4d66ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,9 @@ LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") INCLUDE(libLTEPackage) #setup cpack +include(CTest) +set( CTEST_MEMORYCHECK_COMMAND valgrind ) + ######################################################################## # Install Dirs ######################################################################## diff --git a/CTestConfig.cmake b/CTestConfig.cmake new file mode 100644 index 000000000..32743e0ba --- /dev/null +++ b/CTestConfig.cmake @@ -0,0 +1,13 @@ +## This file should be placed in the root directory of your project. +## Then modify the CMakeLists.txt file in the root directory of your +## project to incorporate the testing dashboard. +## # The following are required to uses Dart and the Cdash dashboard +## ENABLE_TESTING() +## INCLUDE(CTest) +set(CTEST_PROJECT_NAME "libLTE") +set(CTEST_NIGHTLY_START_TIME "00:00:00 GMT") + +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "my.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=libLTE") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a93eda319..b82f3fadd 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,12 +32,6 @@ target_link_libraries(ll_example lte) add_executable(synch_test synch_test.c) target_link_libraries(synch_test lte) -add_executable(equalizer_test equalizer_test.c) -target_link_libraries(equalizer_test lte) - -add_executable(viterbi_test viterbi_test.c) -target_link_libraries(viterbi_test lte) - add_executable(mib_test mib_test.c) target_link_libraries(mib_test lte) diff --git a/examples/enodeb_bch.c b/examples/enodeb_bch.c index 4250ae8a5..8a01c51d2 100644 --- a/examples/enodeb_bch.c +++ b/examples/enodeb_bch.c @@ -39,7 +39,7 @@ #endif char *output_file_name = NULL; -int nof_frames=-1; +int nof_slots=-1; int cell_id = 1; int nof_prb = 6; char *uhd_args = ""; @@ -66,7 +66,7 @@ void usage(char *prog) { printf("\t UHD is disabled. CUHD library not available\n"); #endif printf("\t-o output_file [Default USRP]\n"); - printf("\t-n number of frames [Default %d]\n", nof_frames); + printf("\t-n number of frames [Default %d]\n", nof_slots); printf("\t-c cell id [Default %d]\n", cell_id); printf("\t-p nof_prb [Default %d]\n", nof_prb); printf("\t-v [set verbose to debug, default none]\n"); @@ -92,7 +92,7 @@ void parse_args(int argc, char **argv) { output_file_name = argv[optind]; break; case 'n': - nof_frames = atoi(argv[optind]); + nof_slots = atoi(argv[optind]); break; case 'p': nof_prb = atoi(argv[optind]); @@ -238,7 +238,7 @@ int main(int argc, char **argv) { nf = 0; - while(nf -#include -#include -#include - -#include "lte.h" - -char *input_file_name; -int nof_frames=1; -int cell_id = 0; -int port_id = 0; -int nof_prb = 6; -lte_cp_t cp = CPNORM; -int file_binary = 0; - -int in_slot_length() { - if (CP_ISNORM(cp)) { - return SLOT_LEN_CPNORM(lte_symbol_sz(nof_prb)); - } else { - return SLOT_LEN_CPEXT(lte_symbol_sz(nof_prb)); - } -} - -int slot_length() { - return CP_NSYMB(cp)*lte_symbol_sz(nof_prb); -} - - -void usage(char *prog) { - printf("Usage: %s [bncprev] -i input_file\n", prog); - printf("\t-b input file is binary [Default no]\n"); - printf("\t-n number of slots [Default %d]\n", nof_frames); - printf("\t-c cell_id [Default %d]\n", cell_id); - printf("\t-p port_id [Default %d]\n", port_id); - printf("\t-r nof_prb [Default %d]\n", nof_prb); - printf("\t-e [extended cyclic prefix, Default normal]\n"); - printf("\t-v [set verbose to debug, default none]\n"); -} - -void parse_args(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "bincprev")) != -1) { - switch(opt) { - case 'b': - file_binary = 1; - break; - case 'i': - input_file_name = argv[optind]; - break; - case 'n': - nof_frames = atoi(argv[optind]); - break; - case 'c': - cell_id = atoi(argv[optind]); - break; - case 'p': - port_id = atoi(argv[optind]); - break; - case 'r': - nof_prb = atoi(argv[optind]); - break; - case 'e': - cp = CPEXT; - break; - case 'v': - PRINT_DEBUG; - break; - default: - usage(argv[0]); - exit(-1); - } - } - if (!input_file_name) { - usage(argv[0]); - exit(-1); - } -} - -int main(int argc, char **argv) { - filesource_t fsrc; - lte_fft_t fft; - FILE *f = NULL; - chest_t eq; - int slot_cnt; - cf_t *input = NULL; - cf_t *outfft = NULL; - cf_t *ce = NULL; - int i; - - if (argc < 3) { - usage(argv[0]); - exit(-1); - } - - parse_args(argc,argv); - - if (filesource_init(&fsrc, input_file_name, file_binary?COMPLEX_FLOAT_BIN:COMPLEX_FLOAT)) { - fprintf(stderr, "Error opening file %s\n", input_file_name); - goto do_exit; - } - f = fopen("output.m", "w"); - if (!f) { - perror("fopen"); - goto do_exit; - } - - input = malloc(in_slot_length()*sizeof(cf_t)); - if (!input) { - perror("malloc"); - goto do_exit; - } - outfft = malloc(slot_length()*sizeof(cf_t)); - if (!outfft) { - perror("malloc"); - goto do_exit; - } - ce = malloc(nof_prb * RE_X_RB * CP_NSYMB(cp) * sizeof(cf_t)); - if (!ce) { - perror("malloc"); - goto do_exit; - } - - if (lte_fft_init(&fft, cp, nof_prb)) { - fprintf(stderr, "Error: initializing FFT\n"); - goto do_exit; - } - if (chest_init(&eq, LINEAR, cp, nof_prb, port_id+1)) { - fprintf(stderr, "Error initializing equalizer\n"); - goto do_exit; - } - if (chest_ref_LTEDL(&eq, cell_id)) { - fprintf(stderr, "Error initializing reference signal\n"); - goto do_exit; - } - - bzero(input, sizeof(cf_t) * in_slot_length()); - bzero(outfft, sizeof(cf_t) * slot_length()); - - fprintf(f, "ce=zeros(%d, %d);\n", nof_frames * CP_NSYMB(cp), nof_prb * RE_X_RB); - /* read all file or nof_slots */ - slot_cnt = 0; - while (in_slot_length() == filesource_read(&fsrc, input, in_slot_length()) - && (slot_cnt < nof_frames || nof_frames == -1)) { - - fprintf(f, "infft="); - vec_fprint_c(f, input, in_slot_length()); - fprintf(f, ";\n"); - - lte_fft_run(&fft, input, outfft); - - fprintf(f, "outfft="); - vec_fprint_c(f, outfft, CP_NSYMB(cp) * nof_prb * RE_X_RB); - fprintf(f, ";\n"); - - chest_ce_slot_port(&eq, outfft, ce, slot_cnt%20, port_id); - - chest_fprint(&eq, f, slot_cnt%20, port_id); - - for (i=0;i -#include -#include -#include +#include +#include +#include #include #include #include #include -#include #define PI 3.14159265358979323846 using namespace std; -typedef vector< complex > FloatVec; +typedef vector > FloatVec; -void threadMain1() -{ - Complexplot plot; - plot.setTitle("Float"); - plot.setXAxisRange(0,2); - plot.setYAxisScale(Complexplot::Magnitude, 0.9, 1.1); +void *threadMain1(void *arg) { + Complexplot plot; + plot.setTitle("Float"); + plot.setXAxisRange(0, 2); + plot.setYAxisScale(Complexplot::Magnitude, 0.9, 1.1); - int n=1024; - float step = 2.0*PI/n; - complex* data = new complex[n]; - for(int i=0;i* data = new complex [n]; + for (int i = 0; i < n; i++) + data[i] = polar(1.0f, step * i); - plot.setNewData(data, n); + plot.setNewData(data, n); - for(int i=0;i* data = new complex[n]; - for(int i=0;i* data = new complex [n]; + for (int i = 0; i < n; i++) + data[i] = polar(1.0, step * i); - plot.setNewData(data, n); + plot.setNewData(data, n); - for(int i=0;i("Compleplot_Basic_Test"), NULL }; + QApplication a(argc2, argv2); + pthread_t threads[3]; + int i; -BOOST_AUTO_TEST_CASE(Complexplot_Basic_Test) -{ - int argc = 1; - char* argv[] = { const_cast("Compleplot_Basic_Test"), NULL }; - QApplication a(argc, argv); + if (pthread_create(&threads[0], NULL, threadMain1, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[1], NULL, threadMain2, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[2], NULL, threadMain3, NULL)) { + perror("pthread_create"); + exit(-1); + } - boost::scoped_ptr< boost::thread > thread1_; - boost::scoped_ptr< boost::thread > thread2_; - boost::scoped_ptr< boost::thread > thread3_; + qApp->exec(); - thread1_.reset( new boost::thread( &threadMain1 ) ); - thread2_.reset( new boost::thread( &threadMain2 ) ); - thread3_.reset( new boost::thread( &threadMain3 ) ); - - qApp->exec(); - thread1_->join(); - thread2_->join(); - thread3_->join(); + for (i=0;i<3;i++) { + pthread_join(threads[i], NULL); + } + exit(0); } -BOOST_AUTO_TEST_SUITE_END() diff --git a/graphics/lib/realplot/test/CMakeLists.txt b/graphics/lib/realplot/test/CMakeLists.txt index a5f5ba322..3168de705 100644 --- a/graphics/lib/realplot/test/CMakeLists.txt +++ b/graphics/lib/realplot/test/CMakeLists.txt @@ -24,9 +24,8 @@ # Build tests ######################################################################## #turn the test cpp file into an executable with an int main() function -ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN) INCLUDE_DIRECTORIES(..) ADD_EXECUTABLE(realplot_test realplot_test.cpp) -TARGET_LINK_LIBRARIES(realplot_test ${Boost_LIBRARIES} graphics) +TARGET_LINK_LIBRARIES(realplot_test pthread graphics) ADD_TEST(realplot_test realplot_test) diff --git a/graphics/lib/realplot/test/realplot_test.cpp b/graphics/lib/realplot/test/realplot_test.cpp index c2f4dd9f7..e6a00219d 100644 --- a/graphics/lib/realplot/test/realplot_test.cpp +++ b/graphics/lib/realplot/test/realplot_test.cpp @@ -35,96 +35,91 @@ #include "Realplot.h" -#include -#include -#include -#include +#include +#include +#include #include #include #include #include -#include -typedef std::vector FloatVec; +typedef std::vector FloatVec; template -void getPoints(T* data, int numPoints) -{ - for(int i=0;i -void getPoints(Iterator begin, Iterator end) -{ - for(;begin!=end;begin++) - { - *begin = 10*((double)rand()/RAND_MAX); - } +void getPoints(Iterator begin, Iterator end) { + for (; begin != end; begin++) { + *begin = 10 * ((double) rand() / RAND_MAX); + } } -void threadMain1() -{ - Realplot plot; +void *threadMain1(void *arg) { + Realplot plot; - float data[1024]; + float data[1024]; - for(int i=0;i<10;i++) - { - getPoints(data, 504); - plot.setNewData(data, 504); - boost::this_thread::sleep(boost::posix_time::milliseconds(5)); - } + for (int i = 0; i < 100; i++) { + getPoints(data, 504); + plot.setNewData(data, 504); + boost::this_thread::sleep(boost::posix_time::milliseconds(5)); + } + return NULL; } -void threadMain2() -{ - Realplot plot; - double data[1024]; +void *threadMain2(void *arg) { + Realplot plot; + double data[1024]; - for(int i=0;i<10000;i++) - { - getPoints(data, 504); - plot.setNewData(data, 504); - boost::this_thread::sleep(boost::posix_time::milliseconds(5)); - } + for (int i = 0; i < 100; i++) { + getPoints(data, 504); + plot.setNewData(data, 504); + usleep(5000); + } + return NULL; } -void threadMain3() -{ - Realplot plot; - FloatVec v(1024); +void *threadMain3(void *arg) { + Realplot plot; + FloatVec v(1024); - for(int i=0;i<10000;i++) - { - getPoints(v.begin(), v.end()); - plot.setNewData(v.begin(), v.end()); - boost::this_thread::sleep(boost::posix_time::milliseconds(10)); - } + for (int i = 0; i < 100; i++) { + getPoints(v.begin(), v.end()); + plot.setNewData(v.begin(), v.end()); + usleep(5000); + } + return NULL; } -BOOST_AUTO_TEST_SUITE (Realplot_Test) +int main(int argc, char *argv[]) { + int argc2 = 1; + char* argv2[] = { const_cast("Realplot_Basic_Test"), NULL }; + QApplication a(argc2, argv2); + pthread_t threads[3]; + int i; -BOOST_AUTO_TEST_CASE(Realplot_Basic_Test) -{ - int argc = 1; - char* argv[] = { const_cast("Realplot_Basic_Test"), NULL }; - QApplication a(argc, argv); + if (pthread_create(&threads[0], NULL, threadMain1, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[1], NULL, threadMain2, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[2], NULL, threadMain3, NULL)) { + perror("pthread_create"); + exit(-1); + } - boost::scoped_ptr< boost::thread > thread1_; - boost::scoped_ptr< boost::thread > thread2_; - boost::scoped_ptr< boost::thread > thread3_; + qApp->exec(); - thread1_.reset( new boost::thread( &threadMain1 ) ); - thread2_.reset( new boost::thread( &threadMain2 ) ); - thread3_.reset( new boost::thread( &threadMain3 ) ); - - qApp->exec(); - thread1_->join(); - thread2_->join(); - thread3_->join(); + for (i=0;i<3;i++) { + pthread_join(threads[i], NULL); + } + exit(0); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/graphics/lib/scatterplot/test/CMakeLists.txt b/graphics/lib/scatterplot/test/CMakeLists.txt index 432dd8847..9b373bca8 100644 --- a/graphics/lib/scatterplot/test/CMakeLists.txt +++ b/graphics/lib/scatterplot/test/CMakeLists.txt @@ -23,10 +23,8 @@ ######################################################################## # Build tests ######################################################################## -#turn the test cpp file into an executable with an int main() function -ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN) INCLUDE_DIRECTORIES(..) ADD_EXECUTABLE(scatterplot_test scatterplot_test.cpp) -TARGET_LINK_LIBRARIES(scatterplot_test ${Boost_LIBRARIES} graphics) +TARGET_LINK_LIBRARIES(scatterplot_test pthread graphics) ADD_TEST(scatterplot_test scatterplot_test) diff --git a/graphics/lib/scatterplot/test/scatterplot_test.cpp b/graphics/lib/scatterplot/test/scatterplot_test.cpp index 4f1ccc6f1..a40eabc58 100644 --- a/graphics/lib/scatterplot/test/scatterplot_test.cpp +++ b/graphics/lib/scatterplot/test/scatterplot_test.cpp @@ -35,99 +35,94 @@ #include "Scatterplot.h" -#include -#include -#include -#include +#include +#include +#include #include #include #include #include -#include typedef std::complex Cplx; -typedef std::vector CplxVec; +typedef std::vector CplxVec; template -void getPoints(std::complex* data, int numPoints) -{ - for(int i=0;i(2*((T)rand()/RAND_MAX)-1, - 2*((T)rand()/RAND_MAX)-1); - } +void getPoints(std::complex* data, int numPoints) { + for (int i = 0; i < numPoints; i++) { + data[i] = std::complex(2 * ((T) rand() / RAND_MAX) - 1, + 2 * ((T) rand() / RAND_MAX) - 1); + } } template -void getPoints(Iterator begin, Iterator end) -{ - for(;begin!=end;begin++) - { - float r = 2*((double)rand()/RAND_MAX)-1; - float i = 2*((double)rand()/RAND_MAX)-1; - *begin = Cplx(r,i); - } +void getPoints(Iterator begin, Iterator end) { + for (; begin != end; begin++) { + float r = 2 * ((double) rand() / RAND_MAX) - 1; + float i = 2 * ((double) rand() / RAND_MAX) - 1; + *begin = Cplx(r, i); + } } -void threadMain1() -{ - Scatterplot plot; - std::complex data[1024]; +void *threadMain1(void *arg) { + Scatterplot plot; + std::complex data[1024]; - for(int i=0;i<10;i++) - { - getPoints(data, 1024); - plot.setNewData(data, 1024); - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - } + for (int i = 0; i < 10; i++) { + getPoints(data, 1024); + plot.setNewData(data, 1024); + usleep(100000); + } + return NULL; } -void threadMain2() -{ - Scatterplot plot; - std::complex data[1024]; +void *threadMain2(void *arg) { + Scatterplot plot; + std::complex data[1024]; - for(int i=0;i<10;i++) - { - getPoints(data, 1024); - plot.setNewData(data, 1024); - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - } + for (int i = 0; i < 10; i++) { + getPoints(data, 1024); + plot.setNewData(data, 1024); + usleep(100000); + } + return NULL; } -void threadMain3() -{ - Scatterplot plot; - CplxVec v(1024); +void *threadMain3(void *arg) { + Scatterplot plot; + CplxVec v(1024); - for(int i=0;i<10;i++) - { - getPoints(v.begin(), v.end()); - plot.setNewData(v.begin(), v.end()); - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - } + for (int i = 0; i < 10; i++) { + getPoints(v.begin(), v.end()); + plot.setNewData(v.begin(), v.end()); + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + return NULL; } -BOOST_AUTO_TEST_SUITE (Scatterplot_Test) +int main(int argc, char *argv[]) { + int argc2 = 1; + char* argv2[] = { const_cast("Scatterplot_Basic_Test"), NULL }; + QApplication a(argc2, argv2); + pthread_t threads[3]; + int i; -BOOST_AUTO_TEST_CASE(Scatterplot_Basic_Test) -{ - int argc = 1; - char* argv[] = { const_cast("Scatterplot_Basic_Test"), NULL }; - QApplication a(argc, argv); + if (pthread_create(&threads[0], NULL, threadMain1, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[1], NULL, threadMain2, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[2], NULL, threadMain3, NULL)) { + perror("pthread_create"); + exit(-1); + } - boost::scoped_ptr< boost::thread > thread1_; - boost::scoped_ptr< boost::thread > thread2_; - boost::scoped_ptr< boost::thread > thread3_; + qApp->exec(); - thread1_.reset( new boost::thread( &threadMain1 ) ); - thread2_.reset( new boost::thread( &threadMain2 ) ); - thread3_.reset( new boost::thread( &threadMain3 ) ); - - qApp->exec(); - thread1_->join(); - thread2_->join(); - thread3_->join(); + for (i=0;i<3;i++) { + pthread_join(threads[i], NULL); + } + exit(0); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/graphics/lib/waterfallplot/test/Waterfallplot_test.cpp b/graphics/lib/waterfallplot/test/Waterfallplot_test.cpp index db96b6333..84dd958c8 100644 --- a/graphics/lib/waterfallplot/test/Waterfallplot_test.cpp +++ b/graphics/lib/waterfallplot/test/Waterfallplot_test.cpp @@ -35,94 +35,93 @@ #include "Waterfallplot.h" -#include -#include -#include -#include + +#include +#include +#include #include #include #include -#include #define PI 3.14159265358979323846 using namespace std; -void threadMain1() -{ - int n=2048; - Waterfallplot plot(n,n); - plot.setTitle("Float"); +void *threadMain1(void *arg) { + int n = 2048; + Waterfallplot plot(n, n); + plot.setTitle("Float"); - float step = 1.0*PI/n; - float* data = new float[n*2]; - for(int i=0;i data; - data.resize(n*2); - for(int i=0;i data; + data.resize(n * 2); + for (int i = 0; i < n * 2; i++) + data[i] = sin(step * i); - for(int i=0;i("Waterfallplot_Init_Test"), NULL }; + QApplication a(argc2, argv2); + pthread_t threads[3]; + int i; -BOOST_AUTO_TEST_CASE(Waterfallplot_Init_Test) -{ - int argc = 1; - char* argv[] = { const_cast("Waterfallplot_Init_Test"), NULL }; - QApplication a(argc, argv); + if (pthread_create(&threads[0], NULL, threadMain1, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[1], NULL, threadMain2, NULL)) { + perror("pthread_create"); + exit(-1); + } + if (pthread_create(&threads[2], NULL, threadMain3, NULL)) { + perror("pthread_create"); + exit(-1); + } - boost::scoped_ptr< boost::thread > thread1_; - boost::scoped_ptr< boost::thread > thread2_; - boost::scoped_ptr< boost::thread > thread3_; + qApp->exec(); - thread1_.reset( new boost::thread( &threadMain1 ) ); - thread2_.reset( new boost::thread( &threadMain2 ) ); - thread3_.reset( new boost::thread( &threadMain3 ) ); + for (i = 0; i < 3; i++) { + pthread_join(threads[i], NULL); + } + exit(0); - qApp->exec(); - thread1_->join(); - thread2_->join(); - thread3_->join(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/lte/lib/CMakeLists.txt b/lte/lib/CMakeLists.txt index 6d3888e69..f4d09f9a2 100644 --- a/lte/lib/CMakeLists.txt +++ b/lte/lib/CMakeLists.txt @@ -30,6 +30,8 @@ INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) IF(${DISABLE_VOLK}) IF(${DISABLE_VOLK} EQUAL 0) FIND_PACKAGE(Volk) + ELSE(${DISABLE_VOLK} EQUAL 0) + MESSAGE(STATUS "VOLK library disabled (DISABLE_VOLK=1)") ENDIF(${DISABLE_VOLK} EQUAL 0) ELSE(${DISABLE_VOLK}) FIND_PACKAGE(Volk) @@ -63,7 +65,17 @@ ELSE(VOLK_FOUND) ENDIF(VOLK_FOUND) - +######################################################################## +# Recurse subdirectories and find all directories with a CMakeLists.txt file in it +######################################################################## + +FILE(GLOB_RECURSE cmakefiles CMakeLists.txt) +FOREACH (_file ${cmakefiles}) + GET_FILENAME_COMPONENT(dir ${_file} PATH) + IF (NOT ${dir} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) + ADD_SUBDIRECTORY(${dir}) + ENDIF () +ENDFOREACH() diff --git a/lte/lib/ch_estimation/test/CMakeLists.txt b/lte/lib/ch_estimation/test/CMakeLists.txt new file mode 100644 index 000000000..04b6d85b8 --- /dev/null +++ b/lte/lib/ch_estimation/test/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2012-2013 The libLTE Developers. See the +# COPYRIGHT file at the top-level directory of this distribution. +# +# This file is part of the libLTE library. +# +# libLTE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# libLTE 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 Lesser General Public License for more details. +# +# A copy of the GNU Lesser 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/. +# + +######################################################################## +# Channel Estimation TEST +######################################################################## + +ADD_EXECUTABLE(chest_test chest_test.c) +TARGET_LINK_LIBRARIES(chest_test lte) + +ADD_TEST(chest_test_all_cellids chest_test) + + diff --git a/lte/lib/ch_estimation/test/chest_test.c b/lte/lib/ch_estimation/test/chest_test.c new file mode 100644 index 000000000..0162f3222 --- /dev/null +++ b/lte/lib/ch_estimation/test/chest_test.c @@ -0,0 +1,251 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2014 The libLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the libLTE library. + * + * libLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * libLTE 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 Lesser General Public License for more details. + * + * A copy of the GNU Lesser 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 +#include +#include +#include +#include + +#include "lte.h" + +int cell_id = -1; +int nof_prb = 6; +lte_cp_t cp = CPNORM; + +char *output_matlab = NULL; + +void usage(char *prog) { + printf("Usage: %s [recov]\n", prog); + + printf("\t-r nof_prb [Default %d]\n", nof_prb); + printf("\t-e extended cyclic prefix [Default normal]\n"); + + printf("\t-c cell_id (-1 tests all). [Default %d]\n", cell_id); + + printf("\t-o output matlab file [Default %s]\n",output_matlab?output_matlab:"None"); + printf("\t-v increase verbosity\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "recov")) != -1) { + switch(opt) { + case 'r': + nof_prb = atoi(argv[optind]); + break; + case 'e': + cp = CPEXT; + break; + case 'c': + cell_id = atoi(argv[optind]); + break; + case 'o': + output_matlab = argv[optind]; + break; + case 'v': + verbose++; + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +int check_mse(float mod, float arg, int n_port) { + INFO("mod=%.4f, arg=%.4f, n_port=%d\n", mod, arg, n_port); + switch(n_port) { + case 0: + if (mod > 0.029) { + return -1; + } + if (arg > 0.029) { + return -1; + } + break; + case 1: + if (mod > 0.012) { + return -1; + } + if (arg > 0.012) { + return -1; + } + break; + case 2: + case 3: + if (mod > 3.33) { + return -1; + } + if (arg > 0.63) { + return -1; + } + break; + default: + return -1; + } + return 0; +} + +int main(int argc, char **argv) { + chest_t eq; + cf_t *input = NULL, *ce = NULL, *h = NULL; + refsignal_t refs; + int i, j, n_port, n_slot, cid, num_re; + int ret = -1; + int max_cid; + FILE *fmatlab = NULL; + float mse_mag, mse_phase; + + parse_args(argc,argv); + + if (output_matlab) { + fmatlab=fopen(output_matlab, "w"); + if (!fmatlab) { + perror("fopen"); + goto do_exit; + } + } + + num_re = nof_prb * RE_X_RB * CP_NSYMB(cp); + + input = malloc(num_re * sizeof(cf_t)); + if (!input) { + perror("malloc"); + goto do_exit; + } + h = malloc(num_re * sizeof(cf_t)); + if (!h) { + perror("malloc"); + goto do_exit; + } + ce = malloc(num_re * sizeof(cf_t)); + if (!ce) { + perror("malloc"); + goto do_exit; + } + + if (cell_id == -1) { + cid = 0; + max_cid = 149; + } else { + cid = cell_id; + max_cid = cell_id; + } + while(cid <= max_cid) { + if (chest_init(&eq, LINEAR, cp, nof_prb, MAX_PORTS)) { + fprintf(stderr, "Error initializing equalizer\n"); + goto do_exit; + } + + if (chest_ref_LTEDL(&eq, cid)) { + fprintf(stderr, "Error initializing reference signal\n"); + goto do_exit; + } + + for (n_slot=0;n_slot +#include +#include +#include +#include +#include +#include + +#include "lte.h" + +#include "crc_test.h" + +int num_bits = 1000, crc_length = 16; +unsigned int crc_poly = 0x11021; +unsigned int seed = 0; + + +void usage(char *prog) { + printf("Usage: %s [nlps]\n", prog); + printf("\t-n num_bits [Default %d]\n", num_bits); + printf("\t-l crc_length [Default %d]\n", crc_length); + printf("\t-p crc_poly (Hex) [Default 0x%x]\n", crc_poly); + printf("\t-s seed [Default 0=time]\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "nlps")) != -1) { + switch (opt) { + case 'n': + num_bits = atoi(argv[optind]); + break; + case 'l': + crc_length = atoi(argv[optind]); + break; + case 'p': + crc_poly = (unsigned int) strtoul(argv[optind], NULL, 16); + break; + case 's': + seed = (unsigned int) strtoul(argv[optind], NULL, 0); + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +int main(int argc, char **argv) { + int i; + char *data; + unsigned int crc_word, expected_word; + + parse_args(argc, argv); + + data = malloc(sizeof(char) * (num_bits+crc_length)); + if (!data) { + perror("malloc"); + exit(-1); + } + + if (!seed) { + seed = time(NULL); + } + srand(seed); + + // Generate data + for (i=0;i + +typedef struct { + int n; + int l; + unsigned int p; + unsigned int s; + unsigned int word; +}expected_word_t; + + +static expected_word_t expected_words[] = { + {5000, 24, 0x1864CFB, 1, 0x4D0836}, // LTE CRC24A (36.212 Sec 5.1.1) + {5000, 24, 0X1800063, 1, 0x9B68F8}, // LTE CRC24B + {5000, 16, 0x11021, 1, 0xBFFA}, // LTE CRC16 + {5000, 8, 0x19B, 1, 0xF8}, // LTE CRC8 + + {-1, -1, 0, 0, 0} +}; + +int get_expected_word(int n, int l, unsigned int p, unsigned int s, unsigned int *word) { + int i; + i=0; + while(expected_words[i].n != -1) { + if (expected_words[i].l == l + && expected_words[i].p == p + && expected_words[i].s == s) { + break; + } else { + i++; + } + } + if (expected_words[i].n == -1) { + return -1; + } else { + if (word) { + *word = expected_words[i].word; + } + return 0; + } +} diff --git a/examples/viterbi_test.c b/lte/lib/fec/test/viterbi_test.c similarity index 80% rename from examples/viterbi_test.c rename to lte/lib/fec/test/viterbi_test.c index 03fdef3ae..43180f9e5 100644 --- a/examples/viterbi_test.c +++ b/lte/lib/fec/test/viterbi_test.c @@ -35,9 +35,11 @@ #include "lte.h" +#include "viterbi_test.h" + typedef _Complex float cf_t; -int frame_length = 1000, nof_frames = 128; +int frame_length = 1000, nof_slots = 128; float ebno_db = 100.0; unsigned int seed = 0; bool tail_biting = false; @@ -52,7 +54,7 @@ int K = -1; void usage(char *prog) { printf("Usage: %s [nlestk]\n", prog); - printf("\t-n nof_frames [Default %d]\n", nof_frames); + printf("\t-n nof_frames [Default %d]\n", nof_slots); printf("\t-l frame_length [Default %d]\n", frame_length); printf("\t-e ebno in dB [Default scan]\n"); printf("\t-s seed [Default 0=time]\n"); @@ -65,7 +67,7 @@ void parse_args(int argc, char **argv) { while ((opt = getopt(argc, argv, "nlstek")) != -1) { switch (opt) { case 'n': - nof_frames = atoi(argv[optind]); + nof_slots = atoi(argv[optind]); break; case 'l': frame_length = atoi(argv[optind]); @@ -74,7 +76,7 @@ void parse_args(int argc, char **argv) { ebno_db = atof(argv[optind]); break; case 's': - seed = atoi(argv[optind]); + seed = (unsigned int) strtoul(argv[optind], NULL, 0); break; case 't': tail_biting = true; @@ -89,6 +91,34 @@ void parse_args(int argc, char **argv) { } } +void output_matlab(float ber[NTYPES][SNR_POINTS], int snr_points, + convcoder_t cod[NCODS], int ncods) { + int i, j, n; + FILE *f = fopen("viterbi_snr.m", "w"); + if (!f) { + perror("fopen"); + exit(-1); + } + fprintf(f, "ber=["); + for (j = 0; j < NTYPES; j++) { + for (i = 0; i < snr_points; i++) { + fprintf(f, "%g ", ber[j][i]); + } + fprintf(f, "; "); + } + fprintf(f, "];\n"); + fprintf(f, "snr=linspace(%g,%g-%g/%d,%d);\n", SNR_MIN, SNR_MAX, SNR_MAX, + snr_points, snr_points); + fprintf(f, "semilogy(snr,ber,snr,0.5*erfc(sqrt(10.^(snr/10))));\n"); + fprintf(f, "legend('uncoded',"); + for (n=0;n 1) { - printf("\n"); - - FILE *f = fopen("output.m", "w"); - if (!f) { - perror("fopen"); - exit(-1); - } - fprintf(f, "ber=["); - for (j = 0; j < NTYPES; j++) { - for (i = 0; i < snr_points; i++) { - fprintf(f, "%g ", ber[j][i]); - } - fprintf(f, "; "); - } - fprintf(f, "];\n"); - fprintf(f, "snr=linspace(%g,%g-%g/%d,%d);\n", SNR_MIN, SNR_MAX, SNR_MAX, - snr_points, snr_points); - fprintf(f, "semilogy(snr,ber,snr,0.5*erfc(sqrt(10.^(snr/10))));\n"); - fprintf(f, "legend('uncoded',"); - for (n=0;n expected_errors); + } + } else { + printf("\n"); + output_matlab(ber, snr_points, cod, ncods); + printf("Done\n"); + exit(0); + } } diff --git a/lte/lib/fec/test/viterbi_test.h b/lte/lib/fec/test/viterbi_test.h new file mode 100644 index 000000000..c0080b6ff --- /dev/null +++ b/lte/lib/fec/test/viterbi_test.h @@ -0,0 +1,71 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2014 The libLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the libLTE library. + * + * libLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * libLTE 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 Lesser General Public License for more details. + * + * A copy of the GNU Lesser 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 + +typedef struct { + int n; + unsigned int s; + int len; + int k; + bool tail; + float ebno; + int errors; +}expected_errors_t; + + +static expected_errors_t expected_errors[] = { + {1000, 1, 40, 7, true, 0.0, 5363}, + {1000, 1, 40, 7, true, 2.0, 356}, + {1000, 1, 40, 7, true, 3.0, 48}, + {1000, 1, 40, 7, true, 4.5, 0}, + + {100, 1, 1000, 7, true, 0.0, 8753}, + {100, 1, 1000, 7, true, 2.0, 350}, + {100, 1, 1000, 7, true, 3.0, 33}, + {100, 1, 1000, 7, true, 4.5, 0}, + + {-1, -1, -1, -1, true, -1.0, -1} +}; + +int get_expected_errors(int n, unsigned int s, int len, int k, bool tail, float ebno) { + int i; + i=0; + while(expected_errors[i].n != -1) { + if (expected_errors[i].n == n + && expected_errors[i].s == s + && expected_errors[i].len == len + && expected_errors[i].k == k + && expected_errors[i].tail == tail + && expected_errors[i].ebno == ebno) { + break; + } else { + i++; + } + } + return expected_errors[i].errors; +}