From 67b8cf3ee2bb5462f5a0e2f7e6098e0b0df63398 Mon Sep 17 00:00:00 2001 From: ismagom Date: Tue, 11 Mar 2014 13:42:51 -0500 Subject: [PATCH] Added scrambling, ratematching and layer mapping tests --- CMakeLists.txt | 4 + CTestCustom.cmake.in | 15 ++ examples/CMakeLists.txt | 48 ++--- examples/{enodeb_bch.c => pbch_enodeb.c} | 0 examples/{mib_track.c => pbch_ue.c} | 0 examples/{mib_scan_usrp.c => scan_mib.c} | 0 examples/{pss_scan_usrp.c => scan_pss.c} | 0 examples/{rssi_scan_usrp.c => scan_rssi.c} | 0 examples/{synch_test.c => synch_file.c} | 14 +- lte/include/lte/common/base.h | 8 +- lte/include/lte/mimo/layermap.h | 21 ++- lte/include/lte/mimo/precoding.h | 20 ++- lte/include/lte/modem/demod_hard.h | 4 +- lte/lib/ch_estimation/test/CMakeLists.txt | 1 + lte/lib/common/src/fft.c | 3 + lte/lib/common/src/lte.c | 24 +++ lte/lib/common/src/phch_sequence.c | 3 +- lte/lib/common/test/CMakeLists.txt | 34 ++++ lte/lib/common/test/fft_test.c | 141 +++++++++++++++ lte/lib/mimo/src/layermap.c | 194 ++++++++++++++++++--- lte/lib/mimo/src/precoding.c | 157 +++++++++++++---- lte/lib/mimo/test/CMakeLists.txt | 65 +++++++ lte/lib/mimo/test/layermap_test.c | 163 +++++++++++++++++ lte/lib/mimo/test/precoding_test.c | 163 +++++++++++++++++ lte/lib/modem/src/demod_hard.c | 6 +- lte/lib/modem/test/CMakeLists.txt | 40 +++++ lte/lib/modem/test/modem_test.c | 184 +++++++++++++++++++ lte/lib/phch/src/pbch.c | 34 ++-- lte/lib/ratematching/test/CMakeLists.txt | 33 ++++ lte/lib/ratematching/test/rm_conv_test.c | 134 ++++++++++++++ lte/lib/scrambling/test/CMakeLists.txt | 35 ++++ lte/lib/scrambling/test/scrambling_test.c | 165 ++++++++++++++++++ 32 files changed, 1579 insertions(+), 134 deletions(-) create mode 100644 CTestCustom.cmake.in rename examples/{enodeb_bch.c => pbch_enodeb.c} (100%) rename examples/{mib_track.c => pbch_ue.c} (100%) rename examples/{mib_scan_usrp.c => scan_mib.c} (100%) rename examples/{pss_scan_usrp.c => scan_pss.c} (100%) rename examples/{rssi_scan_usrp.c => scan_rssi.c} (100%) rename examples/{synch_test.c => synch_file.c} (94%) create mode 100644 lte/lib/common/test/CMakeLists.txt create mode 100644 lte/lib/common/test/fft_test.c create mode 100644 lte/lib/mimo/test/CMakeLists.txt create mode 100644 lte/lib/mimo/test/layermap_test.c create mode 100644 lte/lib/mimo/test/precoding_test.c create mode 100644 lte/lib/modem/test/CMakeLists.txt create mode 100644 lte/lib/modem/test/modem_test.c create mode 100644 lte/lib/ratematching/test/CMakeLists.txt create mode 100644 lte/lib/ratematching/test/rm_conv_test.c create mode 100644 lte/lib/scrambling/test/CMakeLists.txt create mode 100644 lte/lib/scrambling/test/scrambling_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e3d4d66ce..143fd68ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,10 @@ INCLUDE(libLTEPackage) #setup cpack include(CTest) set( CTEST_MEMORYCHECK_COMMAND valgrind ) +CONFIGURE_FILE( + "${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake" + IMMEDIATE @ONLY) ######################################################################## # Install Dirs diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in new file mode 100644 index 000000000..a66fe53e2 --- /dev/null +++ b/CTestCustom.cmake.in @@ -0,0 +1,15 @@ +SET(CTEST_CUSTOM_MEMCHECK_IGNORE + +# Ignore memcheck for plots. QT errors + + waterfallplot_test + scatterplot_test + realplot_test + complexplot_test + +# Ignore these to, they take too lonk + fft_normal + fft_extened + chest_test_all_cellids +) + diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b82f3fadd..a3f33e811 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -19,8 +19,9 @@ # and at http://www.gnu.org/licenses/. # + ################################################################# -# TO BE MOVED TO UNIT TESTS +# EXAMPLES ################################################################# add_executable(hl_example hl_example.c) @@ -29,8 +30,13 @@ target_link_libraries(hl_example lte) add_executable(ll_example ll_example.c) target_link_libraries(ll_example lte) -add_executable(synch_test synch_test.c) -target_link_libraries(synch_test lte) +add_executable(synch_file synch_file.c) +target_link_libraries(synch_file lte) + + +################################################################# +# TO BE MOVED TO UNIT TESTS +################################################################# add_executable(mib_test mib_test.c) target_link_libraries(mib_test lte) @@ -47,26 +53,26 @@ LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND) # These two can be compiled without UHD or graphics support ################################################################# -add_executable(mib_track mib_track.c) -target_link_libraries(mib_track lte) +add_executable(pbch_ue pbch_ue.c) +target_link_libraries(pbch_ue lte) -add_executable(enodeb_bch enodeb_bch.c) -target_link_libraries(enodeb_bch lte) +add_executable(pbch_enodeb pbch_enodeb.c) +target_link_libraries(pbch_enodeb lte) IF(${CUHD_FIND} EQUAL -1) - SET_TARGET_PROPERTIES(mib_track PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") - SET_TARGET_PROPERTIES(enodeb_bch PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") + SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") + SET_TARGET_PROPERTIES(pbch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") ELSE(${CUHD_FIND} EQUAL -1) - target_link_libraries(mib_track cuhd) - target_link_libraries(enodeb_bch cuhd) + target_link_libraries(pbch_ue cuhd) + target_link_libraries(pbch_enodeb cuhd) ENDIF(${CUHD_FIND} EQUAL -1) IF(${GRAPHICS_FIND} EQUAL -1) - SET_TARGET_PROPERTIES(mib_track PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") - SET_TARGET_PROPERTIES(enodeb_bch PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") + SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") + SET_TARGET_PROPERTIES(pbch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") ELSE(${GRAPHICS_FIND} EQUAL -1) - target_link_libraries(mib_track graphics) - target_link_libraries(enodeb_bch graphics) + target_link_libraries(pbch_ue graphics) + target_link_libraries(pbch_enodeb graphics) ENDIF(${GRAPHICS_FIND} EQUAL -1) @@ -77,14 +83,14 @@ ENDIF(${GRAPHICS_FIND} EQUAL -1) IF(${CUHD_FIND} GREATER -1) - add_executable(rssi_scan_usrp rssi_scan_usrp.c) - target_link_libraries(rssi_scan_usrp lte cuhd ) + add_executable(scan_rssi scan_rssi.c) + target_link_libraries(scan_rssi lte cuhd ) - add_executable(pss_scan_usrp pss_scan_usrp.c) - target_link_libraries(pss_scan_usrp lte cuhd ) + add_executable(scan_pss scan_pss.c) + target_link_libraries(scan_pss lte cuhd ) - add_executable(mib_scan_usrp mib_scan_usrp.c) - target_link_libraries(mib_scan_usrp lte cuhd ) + add_executable(scan_mib scan_mib.c) + target_link_libraries(scan_mib lte cuhd ) MESSAGE(STATUS " UHD examples will be installed.") diff --git a/examples/enodeb_bch.c b/examples/pbch_enodeb.c similarity index 100% rename from examples/enodeb_bch.c rename to examples/pbch_enodeb.c diff --git a/examples/mib_track.c b/examples/pbch_ue.c similarity index 100% rename from examples/mib_track.c rename to examples/pbch_ue.c diff --git a/examples/mib_scan_usrp.c b/examples/scan_mib.c similarity index 100% rename from examples/mib_scan_usrp.c rename to examples/scan_mib.c diff --git a/examples/pss_scan_usrp.c b/examples/scan_pss.c similarity index 100% rename from examples/pss_scan_usrp.c rename to examples/scan_pss.c diff --git a/examples/rssi_scan_usrp.c b/examples/scan_rssi.c similarity index 100% rename from examples/rssi_scan_usrp.c rename to examples/scan_rssi.c diff --git a/examples/synch_test.c b/examples/synch_file.c similarity index 94% rename from examples/synch_test.c rename to examples/synch_file.c index 1a468b3ed..db9a8338b 100644 --- a/examples/synch_test.c +++ b/examples/synch_file.c @@ -37,20 +37,18 @@ char *input_file_name; char *output_file_name="abs_corr.txt"; int nof_slots=100, frame_length=9600, symbol_sz=128; float corr_peak_threshold=25.0; -int file_binary = 0; int out_N_id_2 = 0, force_N_id_2=-1; #define CFO_AUTO -9999.0 float force_cfo = CFO_AUTO; void usage(char *prog) { - printf("Usage: %s [onlt] -i input_file\n", prog); + printf("Usage: %s [olntsNfc] -i input_file\n", prog); printf("\t-o output_file [Default %s]\n", output_file_name); printf("\t-l frame_length [Default %d]\n", frame_length); printf("\t-n number of frames [Default %d]\n", nof_slots); printf("\t-t correlation threshold [Default %g]\n", corr_peak_threshold); printf("\t-s symbol_sz [Default %d]\n", symbol_sz); - printf("\t-b Input files is binary [Default %s]\n", file_binary?"yes":"no"); printf("\t-N out_N_id_2 [Default %d]\n", out_N_id_2); printf("\t-f force_N_id_2 [Default %d]\n", force_N_id_2); printf("\t-c force_cfo [Default disabled]\n"); @@ -58,7 +56,7 @@ void usage(char *prog) { void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "ionltsbNfc")) != -1) { + while ((opt = getopt(argc, argv, "ionltsNfc")) != -1) { switch(opt) { case 'i': input_file_name = argv[optind]; @@ -78,9 +76,6 @@ void parse_args(int argc, char **argv) { case 's': symbol_sz = atof(argv[optind]); break; - case 'b': - file_binary = 1; - break; case 'N': out_N_id_2 = atoi(argv[optind]); break; @@ -130,12 +125,11 @@ int main(int argc, char **argv) { gettimeofday(&tdata[1], NULL); printf("Initializing...");fflush(stdout); - data_type_t type = file_binary?COMPLEX_FLOAT_BIN:COMPLEX_FLOAT; - if (filesource_init(&fsrc, input_file_name, type)) { + if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) { fprintf(stderr, "Error opening file %s\n", input_file_name); exit(-1); } - if (filesink_init(&fsink, output_file_name, type)) { + if (filesink_init(&fsink, output_file_name, COMPLEX_FLOAT_BIN)) { fprintf(stderr, "Error opening file %s\n", output_file_name); exit(-1); } diff --git a/lte/include/lte/common/base.h b/lte/include/lte/common/base.h index ae41c2d78..8212b43d5 100644 --- a/lte/include/lte/common/base.h +++ b/lte/include/lte/common/base.h @@ -34,8 +34,8 @@ #define MAX_PORTS 4 #define MAX_PORTS_CTRL 4 -#define MAX_LAYERS 4 -#define MAX_CODEWORDS 4 +#define MAX_LAYERS 8 +#define MAX_CODEWORDS 2 typedef enum {CPNORM, CPEXT} lte_cp_t; @@ -85,7 +85,7 @@ int lte_voffset(int symbol_id, int cell_id, int nof_ports); typedef enum { - TX_DIVERSITY, SPATIAL_MULTIPLEX + SINGLE_ANTENNA,TX_DIVERSITY, SPATIAL_MULTIPLEX } mimo_type_t; @@ -103,6 +103,8 @@ int lte_band_get_fd_band(int band, lte_earfcn_t *earfcn, int earfcn_start, int e int lte_band_get_fd_band_all(int band, lte_earfcn_t *earfcn, int max_nelems); int lte_band_get_fd_region(enum band_geographical_area region, lte_earfcn_t *earfcn, int max_elems); +int lte_str2mimotype(char *mimo_type_str, mimo_type_t *type); +char *lte_mimotype2str(mimo_type_t type); #endif diff --git a/lte/include/lte/mimo/layermap.h b/lte/include/lte/mimo/layermap.h index 5527d6d7e..9a2f6f9bb 100644 --- a/lte/include/lte/mimo/layermap.h +++ b/lte/include/lte/mimo/layermap.h @@ -31,14 +31,23 @@ typedef _Complex float cf_t; -/* Generates the vector of data symbols "d" based on the vector of layer-mapped symbols "x" +/* Generates the vector of layer-mapped symbols "x" based on the vector of data symbols "d" */ -void layermap_decode(cf_t *x[MAX_LAYERS], cf_t *d[MAX_CODEWORDS], int nof_layers, int nof_cw, - int nof_layer_symbols, mimo_type_t type); +int layermap_single(cf_t *d, cf_t *x, int nof_symbols); +int layermap_diversity(cf_t *d, cf_t *x[MAX_LAYERS], int nof_layers, int nof_symbols); +int layermap_multiplex(cf_t *d[MAX_CODEWORDS], cf_t *x[MAX_LAYERS], int nof_cw, int nof_layers, + int nof_symbols[MAX_CODEWORDS]); +int layermap_type(cf_t *d[MAX_CODEWORDS], cf_t *x[MAX_LAYERS], int nof_cw, int nof_layers, + int nof_symbols[MAX_CODEWORDS], mimo_type_t type); -/* Generates the vector of layer-mapped symbols "x" based on the vector of data symbols "d" + +/* Generates the vector of data symbols "d" based on the vector of layer-mapped symbols "x" */ -void layermap_encode(cf_t *d[MAX_CODEWORDS], cf_t *x[MAX_LAYERS], int nof_layers, int nof_cw, - int nof_symbols, mimo_type_t type); +int layerdemap_single(cf_t *x, cf_t *d, int nof_symbols); +int layerdemap_diversity(cf_t *x[MAX_LAYERS], cf_t *d, int nof_layers, int nof_layer_symbols); +int layerdemap_multiplex(cf_t *x[MAX_LAYERS], cf_t *d[MAX_CODEWORDS], int nof_layers, int nof_cw, + int nof_layer_symbols, int nof_symbols[MAX_CODEWORDS]); +int layerdemap_type(cf_t *x[MAX_LAYERS], cf_t *d[MAX_CODEWORDS], int nof_layers, int nof_cw, + int nof_layer_symbols, int nof_symbols[MAX_CODEWORDS], mimo_type_t type); #endif diff --git a/lte/include/lte/mimo/precoding.h b/lte/include/lte/mimo/precoding.h index 708c61f9c..ea68c5496 100644 --- a/lte/include/lte/mimo/precoding.h +++ b/lte/include/lte/mimo/precoding.h @@ -36,15 +36,21 @@ typedef _Complex float cf_t; * resources on each of the antenna ports. */ -/* Estimates the vector "x" based on the received signal "y" and the channel estimates "ce" - */ -void precoding_decode(cf_t *y[MAX_PORTS], cf_t *ce[MAX_PORTS], - cf_t *x[MAX_LAYERS], int nof_ports, int nof_symbols, - mimo_type_t type); - /* Generates the vector "y" from the input vector "x" */ -void precoding_encode(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_ports, +int precoding_single(cf_t *x, cf_t *y, int nof_symbols); +int precoding_diversity(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_ports, int nof_symbols); +int precoding_type(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_layers, int nof_ports, int nof_symbols, mimo_type_t type); + +/* Estimates the vector "x" based on the received signal "y" and the channel estimates "ce" + */ +int predecoding_single_zf(cf_t *y, cf_t *ce, cf_t *x, int nof_symbols); +int predecoding_diversity_zf(cf_t *y[MAX_PORTS], cf_t *ce[MAX_PORTS], + cf_t *x[MAX_LAYERS], int nof_ports, int nof_symbols); +int predecoding_type(cf_t *y[MAX_PORTS], cf_t *ce[MAX_PORTS], + cf_t *x[MAX_LAYERS], int nof_ports, int nof_layers, int nof_symbols, + mimo_type_t type); + #endif /* PRECODING_H_ */ diff --git a/lte/include/lte/modem/demod_hard.h b/lte/include/lte/modem/demod_hard.h index 8675c9758..4525ff7a1 100644 --- a/lte/include/lte/modem/demod_hard.h +++ b/lte/include/lte/modem/demod_hard.h @@ -42,8 +42,8 @@ typedef struct { void demod_hard_init(demod_hard_t* q); -void demod_hard_table(demod_hard_t* q, enum modem_std table); -int demod_hard_demodulate(demod_hard_t* q, const cf_t* symbols, char *bits, int nsymbols); +void demod_hard_table_set(demod_hard_t* q, enum modem_std table); +int demod_hard_demodulate(demod_hard_t* q, cf_t* symbols, char *bits, int nsymbols); diff --git a/lte/lib/ch_estimation/test/CMakeLists.txt b/lte/lib/ch_estimation/test/CMakeLists.txt index 04b6d85b8..9f4be5ea8 100644 --- a/lte/lib/ch_estimation/test/CMakeLists.txt +++ b/lte/lib/ch_estimation/test/CMakeLists.txt @@ -27,5 +27,6 @@ ADD_EXECUTABLE(chest_test chest_test.c) TARGET_LINK_LIBRARIES(chest_test lte) ADD_TEST(chest_test_all_cellids chest_test) +ADD_TEST(chest_test_cellid chest_test -c 1) diff --git a/lte/lib/common/src/fft.c b/lte/lib/common/src/fft.c index e5fae9226..e6319a5aa 100644 --- a/lte/lib/common/src/fft.c +++ b/lte/lib/common/src/fft.c @@ -71,6 +71,9 @@ int lte_fft_init_(lte_fft_t *q, lte_cp_t cp_type, int nof_prb, dft_dir_t dir) { void lte_fft_free_(lte_fft_t *q) { dft_plan_free(&q->fft_plan); + if (q->tmp) { + free(q->tmp); + } bzero(q, sizeof(lte_fft_t)); } diff --git a/lte/lib/common/src/lte.c b/lte/lib/common/src/lte.c index 74b2734fd..8147b68d1 100644 --- a/lte/lib/common/src/lte.c +++ b/lte/lib/common/src/lte.c @@ -134,6 +134,30 @@ struct lte_band lte_bands[NOF_LTE_BANDS] = { }; #define EOF_BAND 9919 +int lte_str2mimotype(char *mimo_type_str, mimo_type_t *type) { + if (!strcmp(mimo_type_str, "single")) { + *type = SINGLE_ANTENNA; + } else if (!strcmp(mimo_type_str, "diversity")) { + *type = TX_DIVERSITY; + } else if (!strcmp(mimo_type_str, "multiplex")) { + *type = SPATIAL_MULTIPLEX; + } else { + return -1; + } + return 0; +} + +char *lte_mimotype2str(mimo_type_t type) { + switch(type) { + case SINGLE_ANTENNA: + return "single"; + case TX_DIVERSITY: + return "diversity"; + case SPATIAL_MULTIPLEX: + return "multiplex"; + } +} + float get_fd(struct lte_band *band, int earfcn) { return band->fd_low_mhz + 0.1*(earfcn - band->earfcn_offset); } diff --git a/lte/lib/common/src/phch_sequence.c b/lte/lib/common/src/phch_sequence.c index 6b2797859..8525d5d6a 100644 --- a/lte/lib/common/src/phch_sequence.c +++ b/lte/lib/common/src/phch_sequence.c @@ -25,10 +25,11 @@ * */ - +#include #include "lte/common/base.h" #include "lte/common/sequence.h" int sequence_pbch(sequence_t *seq, lte_cp_t cp, int cell_id) { + bzero(seq, sizeof(sequence_t)); return sequence_LTEPRS(seq, CP_ISNORM(cp)?1920:1728, cell_id); } diff --git a/lte/lib/common/test/CMakeLists.txt b/lte/lib/common/test/CMakeLists.txt new file mode 100644 index 000000000..18ed7f8fb --- /dev/null +++ b/lte/lib/common/test/CMakeLists.txt @@ -0,0 +1,34 @@ +# +# 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/. +# + +######################################################################## +# FFT TEST +######################################################################## + +ADD_EXECUTABLE(fft_test fft_test.c) +TARGET_LINK_LIBRARIES(fft_test lte) + +ADD_TEST(fft_normal fft_test) +ADD_TEST(fft_extended fft_test -e) + +ADD_TEST(fft_normal_single fft_test -n 6) +ADD_TEST(fft_extended_single fft_test -e -n 6) + diff --git a/lte/lib/common/test/fft_test.c b/lte/lib/common/test/fft_test.c new file mode 100644 index 000000000..e82206eb8 --- /dev/null +++ b/lte/lib/common/test/fft_test.c @@ -0,0 +1,141 @@ +/** + * + * \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 + +#include "lte.h" + +int nof_prb = -1; +lte_cp_t cp = CPNORM; + +void usage(char *prog) { + printf("Usage: %s\n", prog); + printf("\t-n nof_prb [Default All]\n"); + printf("\t-e extended cyclic prefix [Default Normal]\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "ne")) != -1) { + switch (opt) { + case 'n': + nof_prb = atoi(argv[optind]); + break; + case 'e': + cp = CPEXT; + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + + +int main(int argc, char **argv) { + lte_fft_t fft, ifft; + cf_t *input, *outfft, *outifft; + float mse; + int n_prb, max_prb, n_re; + int i; + + parse_args(argc, argv); + + if (nof_prb == -1) { + n_prb = 6; + max_prb = 100; + } else { + n_prb = nof_prb; + max_prb = nof_prb; + } + while(n_prb <= max_prb) { + n_re = CP_NSYMB(cp) * n_prb * RE_X_RB; + + printf("Running test for %d PRB, %d RE... ", n_prb, n_re);fflush(stdout); + + input = malloc(sizeof(cf_t) * n_re); + if (!input) { + perror("malloc"); + exit(-1); + } + outfft = malloc(sizeof(cf_t) * SLOT_LEN_CPNORM(lte_symbol_sz(n_prb))); + if (!outfft) { + perror("malloc"); + exit(-1); + } + outifft = malloc(sizeof(cf_t) * n_re); + if (!outifft) { + perror("malloc"); + exit(-1); + } + + if (lte_fft_init(&fft, cp, n_prb)) { + fprintf(stderr, "Error initializing FFT\n"); + exit(-1); + } + if (lte_ifft_init(&ifft, cp, n_prb)) { + fprintf(stderr, "Error initializing iFFT\n"); + exit(-1); + } + + for (i=0;i= 0.05) { + printf("MSE too large\n"); + exit(-1); + } + + lte_fft_free(&fft); + lte_ifft_free(&ifft); + + free(input); + free(outfft); + free(outifft); + + n_prb++; + } + fftwf_cleanup(); + exit(0); +} diff --git a/lte/lib/mimo/src/layermap.c b/lte/lib/mimo/src/layermap.c index 07de82911..cd685dcd0 100644 --- a/lte/lib/mimo/src/layermap.c +++ b/lte/lib/mimo/src/layermap.c @@ -33,46 +33,182 @@ #include "lte/common/base.h" #include "lte/mimo/layermap.h" -/* Generates the vector of data symbols "d" based on the vector of layer-mapped symbols "x" + + +int layermap_single(cf_t *d, cf_t *x, int nof_symbols) { + memcpy(x, d, sizeof(cf_t) * nof_symbols); + return nof_symbols; +} + +int layermap_diversity(cf_t *d, cf_t *x[MAX_LAYERS], int nof_layers, int nof_symbols) { + int i, j; + for (i=0;i MAX_CODEWORDS) { + fprintf(stderr, "Maximum number of codewords is %d (nof_cw=%d)\n", MAX_CODEWORDS, nof_cw); + return -1; + } + if (nof_layers > MAX_LAYERS) { + fprintf(stderr, "Maximum number of layers is %d (nof_layers=%d)\n", MAX_LAYERS, nof_layers); + return -1; + } + if (nof_layers < nof_cw) { + fprintf(stderr, "Number of codewords must be lower or equal than number of layers\n"); + return -1; + } - switch(nof_layers) { - case 1: - memcpy(d[0], x[0], nof_layer_symbols * sizeof(cf_t)); + switch(type) { + case SINGLE_ANTENNA: + if (nof_cw == 1 && nof_layers == 1) { + return layermap_single(x[0], d[0], nof_symbols[0]); + } else { + fprintf(stderr, "Number of codewords and layers must be 1 for transmission on single antenna ports\n"); + return -1; + } break; - case 2: - switch(type) { - case TX_DIVERSITY: - for (i=0;i MAX_CODEWORDS) { + fprintf(stderr, "Maximum number of codewords is %d (nof_cw=%d)\n", MAX_CODEWORDS, nof_cw); + return -1; + } + if (nof_layers > MAX_LAYERS) { + fprintf(stderr, "Maximum number of layers is %d (nof_layers=%d)\n", MAX_LAYERS, nof_layers); + return -1; + } + if (nof_layers < nof_cw) { + fprintf(stderr, "Number of codewords must be lower or equal than number of layers\n"); + return -1; + } + + switch(type) { + case SINGLE_ANTENNA: + if (nof_cw == 1 && nof_layers == 1) { + nof_symbols[0] = layerdemap_single(x[0], d[0], nof_layer_symbols); + nof_symbols[1] = 0; + } else { + fprintf(stderr, "Number of codewords and layers must be 1 for transmission on single antenna ports\n"); + return -1; + } + break; + case TX_DIVERSITY: + if (nof_cw == 1) { + if (nof_layers == 2 || nof_layers == 4) { + nof_symbols[0] = layerdemap_diversity(x, d[0], nof_layers, nof_layer_symbols); + nof_symbols[1] = 0; + } else { + fprintf(stderr, "Number of layers must be 2 or 4 for transmit diversity\n"); + return -1; + } + } else { + fprintf(stderr, "Number of codewords must be 1 for transmit diversity\n"); + return -1; + } + break; + case SPATIAL_MULTIPLEX: + return layerdemap_multiplex(x, d, nof_layers, nof_cw, nof_layer_symbols, nof_symbols); break; - default: - printf("Error: Unsupported nof_ports=%d\n", nof_layers); - return; } + return 0; } - diff --git a/lte/lib/mimo/src/precoding.c b/lte/lib/mimo/src/precoding.c index 75f64ecfc..340ef2f0d 100644 --- a/lte/lib/mimo/src/precoding.c +++ b/lte/lib/mimo/src/precoding.c @@ -31,56 +31,141 @@ #include #include #include +#include #include "lte/common/base.h" #include "lte/mimo/precoding.h" #include "lte/utils/vector.h" +int precoding_single(cf_t *x, cf_t *y, int nof_symbols) { + memcpy(y, x, nof_symbols * sizeof(cf_t)); + return nof_symbols; +} +int precoding_diversity(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_ports, int nof_symbols) { + int i; + if (nof_ports == 2) { + /* FIXME: Use VOLK here */ + for (i=0;i MAX_PORTS) { + fprintf(stderr, "Maximum number of ports is %d (nof_ports=%d)\n", MAX_PORTS, nof_ports); + return -1; + } + if (nof_layers > MAX_LAYERS) { + fprintf(stderr, "Maximum number of layers is %d (nof_layers=%d)\n", MAX_LAYERS, nof_layers); + return -1; + } + + switch(type) { + case SINGLE_ANTENNA: + if (nof_ports == 1 && nof_layers == 1) { + return precoding_single(x[0], y[0], nof_symbols); + } else { + fprintf(stderr, "Number of ports and layers must be 1 for transmission on single antenna ports\n"); + return -1; + } + break; + case TX_DIVERSITY: + if (nof_ports == nof_layers) { + return precoding_diversity(y, x, nof_ports, nof_symbols); + } else { + fprintf(stderr, "Error number of layers must equal number of ports in transmit diversity\n"); + return -1; + } + case SPATIAL_MULTIPLEX: + fprintf(stderr, "Spatial multiplexing not supported\n"); + return -1; + } + return 0; +} + +/* ZF detector */ +int predecoding_single_zf(cf_t *y, cf_t *ce, cf_t *x, int nof_symbols) { + vec_div_ccc(y, ce, x, nof_symbols); + return nof_symbols; +} + +/* ZF detector */ +int predecoding_diversity_zf(cf_t *y[MAX_PORTS], cf_t *ce[MAX_PORTS], + cf_t *x[MAX_LAYERS], int nof_ports, int nof_symbols) { int i; cf_t h0, h1, r0, r1; float hh; - - switch(nof_ports) { - case 1: - vec_div_ccc(y[0], ce[0], x[0], nof_symbols); - break; - case 2: - switch(type) { - case TX_DIVERSITY: - /* FIXME: Use VOLK here */ - // 6.3.4.3 - for (i=0;i MAX_PORTS) { + fprintf(stderr, "Maximum number of ports is %d (nof_ports=%d)\n", MAX_PORTS, nof_ports); + return -1; + } + if (nof_layers > MAX_LAYERS) { + fprintf(stderr, "Maximum number of layers is %d (nof_layers=%d)\n", MAX_LAYERS, nof_layers); + return -1; + } + + + switch(type) { + case SINGLE_ANTENNA: + if (nof_ports == 1 && nof_layers == 1) { + return predecoding_single_zf(y[0], ce[0], x[0], nof_symbols); + } else{ + fprintf(stderr, "Number of ports and layers must be 1 for transmission on single antenna ports\n"); + return -1; + } + break; + case TX_DIVERSITY: + if (nof_ports == nof_layers) { + return predecoding_diversity_zf(y, ce, x, nof_ports, nof_symbols); + } else { + fprintf(stderr, "Error number of layers must equal number of ports in transmit diversity\n"); + return -1; + } break; - default: - printf("Error: Unsupported nof_ports=%d\n", nof_ports); - return; + case SPATIAL_MULTIPLEX: + fprintf(stderr, "Spatial multiplexing not supported\n"); + return -1; } + return 0; } + diff --git a/lte/lib/mimo/test/CMakeLists.txt b/lte/lib/mimo/test/CMakeLists.txt new file mode 100644 index 000000000..031f29175 --- /dev/null +++ b/lte/lib/mimo/test/CMakeLists.txt @@ -0,0 +1,65 @@ +# +# 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/. +# + +######################################################################## +# LAYER MAPPING TEST +######################################################################## + +ADD_EXECUTABLE(layermap_test layermap_test.c) +TARGET_LINK_LIBRARIES(layermap_test lte) + +ADD_TEST(layermap_single layermap_test -n 1000 -m single -c 1 -l 1) + +ADD_TEST(layermap_diversity_2 layermap_test -n 1000 -m diversity -c 1 -l 2) +ADD_TEST(layermap_diversity_4 layermap_test -n 1000 -m diversity -c 1 -l 4) + +ADD_TEST(layermap_multiplex_11 layermap_test -n 1000 -m multiplex -c 1 -l 1) +ADD_TEST(layermap_multiplex_12 layermap_test -n 1000 -m multiplex -c 1 -l 2) +ADD_TEST(layermap_multiplex_13 layermap_test -n 1002 -m multiplex -c 1 -l 3) +ADD_TEST(layermap_multiplex_14 layermap_test -n 1000 -m multiplex -c 1 -l 4) +ADD_TEST(layermap_multiplex_15 layermap_test -n 1000 -m multiplex -c 1 -l 5) +ADD_TEST(layermap_multiplex_16 layermap_test -n 1002 -m multiplex -c 1 -l 6) +ADD_TEST(layermap_multiplex_17 layermap_test -n 994 -m multiplex -c 1 -l 7) +ADD_TEST(layermap_multiplex_18 layermap_test -n 1000 -m multiplex -c 1 -l 8) + + +ADD_TEST(layermap_multiplex_22 layermap_test -n 1000 -m multiplex -c 2 -l 2) +ADD_TEST(layermap_multiplex_23 layermap_test -n 1002 -m multiplex -c 2 -l 3) +ADD_TEST(layermap_multiplex_24 layermap_test -n 1000 -m multiplex -c 2 -l 4) +ADD_TEST(layermap_multiplex_25 layermap_test -n 1002 -m multiplex -c 2 -l 5) +ADD_TEST(layermap_multiplex_26 layermap_test -n 1002 -m multiplex -c 2 -l 6) +ADD_TEST(layermap_multiplex_27 layermap_test -n 1000 -m multiplex -c 2 -l 7) +ADD_TEST(layermap_multiplex_28 layermap_test -n 1000 -m multiplex -c 2 -l 8) + + +######################################################################## +# LAYER MAPPING TEST +######################################################################## + + +#ADD_EXECUTABLE(precoding_test precoding_test.c) +#TARGET_LINK_LIBRARIES(precoding_test lte) + + + + + + diff --git a/lte/lib/mimo/test/layermap_test.c b/lte/lib/mimo/test/layermap_test.c new file mode 100644 index 000000000..bcb75d7e1 --- /dev/null +++ b/lte/lib/mimo/test/layermap_test.c @@ -0,0 +1,163 @@ +/** + * + * \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 +#include +#include + +#include "lte.h" + +int nof_symbols = 1000; +int nof_cw = 1, nof_layers = 1; +char *mimo_type_name = NULL; + +void usage(char *prog) { + printf("Usage: %s -m [single|diversity|multiplex] -c [nof_cw] -l [nof_layers]\n", prog); + printf("\t-n num_symbols [Default %d]\n", nof_symbols); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "mcln")) != -1) { + switch (opt) { + case 'n': + nof_symbols = atoi(argv[optind]); + break; + case 'c': + nof_cw = atoi(argv[optind]); + break; + case 'l': + nof_layers = atoi(argv[optind]); + break; + case 'm': + mimo_type_name = argv[optind]; + break; + default: + usage(argv[0]); + exit(-1); + } + } + if (!mimo_type_name) { + usage(argv[0]); + exit(-1); + } +} + +int main(int argc, char **argv) { + int i, j, num_errors, symbols_layer; + cf_t *d[MAX_CODEWORDS], *x[MAX_LAYERS], *dp[MAX_CODEWORDS]; + mimo_type_t type; + int nof_symb_cw[MAX_CODEWORDS]; + int n[2]; + + parse_args(argc, argv); + + if (lte_str2mimotype(mimo_type_name, &type)) { + fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name); + exit(-1); + } + + if (nof_cw > 1) { + n[0] = nof_layers / nof_cw; + n[1] = nof_layers - n[0]; + nof_symb_cw[0] = nof_symbols * n[0]; + nof_symb_cw[1] = nof_symbols * n[1]; + } else { + nof_symb_cw[0] = nof_symbols; + nof_symb_cw[1] = 0; + } + + for (i=0;i +#include +#include +#include +#include +#include +#include +#include + +#include "lte.h" + +int nof_symbols = 1000; +int nof_cw = 1, nof_layers = 1; +char *mimo_type_name = NULL; + +void usage(char *prog) { + printf("Usage: %s -m [single|diversity|multiplex] -c [nof_cw] -l [nof_layers]\n", prog); + printf("\t-n num_symbols [Default %d]\n", nof_symbols); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "mcln")) != -1) { + switch (opt) { + case 'n': + nof_symbols = atoi(argv[optind]); + break; + case 'c': + nof_cw = atoi(argv[optind]); + break; + case 'l': + nof_layers = atoi(argv[optind]); + break; + case 'm': + mimo_type_name = argv[optind]; + break; + default: + usage(argv[0]); + exit(-1); + } + } + if (!mimo_type_name) { + usage(argv[0]); + exit(-1); + } +} + +int main(int argc, char **argv) { + int i, j, num_errors, symbols_layer; + cf_t *d[MAX_CODEWORDS], *x[MAX_LAYERS], *dp[MAX_CODEWORDS]; + mimo_type_t type; + int nof_symb_cw[MAX_CODEWORDS]; + int n[2]; + + parse_args(argc, argv); + + if (lte_str2mimotype(mimo_type_name, &type)) { + fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name); + exit(-1); + } + + if (nof_cw > 1) { + n[0] = nof_layers / nof_cw; + n[1] = nof_layers - n[0]; + nof_symb_cw[0] = nof_symbols * n[0]; + nof_symb_cw[1] = nof_symbols * n[1]; + } else { + nof_symb_cw[0] = nof_symbols; + nof_symb_cw[1] = 0; + } + + for (i=0;itable = table; } -int demod_hard_demodulate(demod_hard_t* q, const cf_t* symbols, char *bits, int nsymbols) { +int demod_hard_demodulate(demod_hard_t* q, cf_t* symbols, char *bits, int nsymbols) { int nbits=-1; switch(q->table) { @@ -68,7 +68,7 @@ int demod_hard_demodulate(demod_hard_t* q, const cf_t* symbols, char *bits, int int demod_hard_initialize(demod_hard_hl* hl) { demod_hard_init(&hl->obj); - demod_hard_table(&hl->obj,hl->init.std); + demod_hard_table_set(&hl->obj,hl->init.std); return 0; } diff --git a/lte/lib/modem/test/CMakeLists.txt b/lte/lib/modem/test/CMakeLists.txt new file mode 100644 index 000000000..7b1689b17 --- /dev/null +++ b/lte/lib/modem/test/CMakeLists.txt @@ -0,0 +1,40 @@ +# +# 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/. +# + +######################################################################## +# MODEM TEST +######################################################################## + +ADD_EXECUTABLE(modem_test modem_test.c) +TARGET_LINK_LIBRARIES(modem_test lte) + +ADD_TEST(modem_bpsk modem_test -n 1020 -m 1) +ADD_TEST(modem_qpsk modem_test -n 1020 -m 2) +ADD_TEST(modem_qam16 modem_test -n 1020 -m 4) +ADD_TEST(modem_qam64 modem_test -n 1020 -m 6) + +ADD_TEST(modem_bpsk_soft modem_test -n 1020 -m 1 -s) +ADD_TEST(modem_qpsk_soft modem_test -n 1020 -m 2 -s) +ADD_TEST(modem_qam16_soft modem_test -n 1020 -m 4 -s) +ADD_TEST(modem_qam64_soft modem_test -n 1020 -m 6 -s) + + + diff --git a/lte/lib/modem/test/modem_test.c b/lte/lib/modem/test/modem_test.c new file mode 100644 index 000000000..1582b611a --- /dev/null +++ b/lte/lib/modem/test/modem_test.c @@ -0,0 +1,184 @@ +/** + * + * \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 +#include +#include + +#include "lte.h" + +int num_bits = 1000; +enum modem_std modulation; +bool soft_output = false, soft_exact = false; + +void usage(char *prog) { + printf("Usage: %s [nmse]\n", prog); + printf("\t-n num_bits [Default %d]\n", num_bits); + printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n"); + printf("\t-s soft outputs [Default hard]\n"); + printf("\t-e soft outputs exact algorithm [Default approx]\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "nmse")) != -1) { + switch (opt) { + case 'n': + num_bits = atoi(argv[optind]); + break; + case 's': + soft_output = true; + break; + case 'e': + soft_exact = true; + break; + case 'm': + switch(atoi(argv[optind])) { + case 1: + modulation = LTE_BPSK; + break; + case 2: + modulation = LTE_QPSK; + break; + case 4: + modulation = LTE_QAM16; + break; + case 6: + modulation = LTE_QAM64; + break; + default: + fprintf(stderr, "Invalid modulation %d. Possible values: " + "(1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64)\n", atoi(argv[optind])); + break; + } + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + + +int main(int argc, char **argv) { + int i; + modem_table_t mod; + demod_hard_t demod_hard; + demod_soft_t demod_soft; + char *input, *output; + cf_t *symbols; + float *llr; + + parse_args(argc, argv); + + /* initialize objects */ + if (modem_table_std(&mod, modulation, soft_output)) { + fprintf(stderr, "Error initializing modem table\n"); + exit(-1); + } + + /* check that num_bits is multiple of num_bits x symbol */ + if (num_bits % mod.nbits_x_symbol) { + fprintf(stderr, "Error num_bits must be multiple of %d\n", mod.nbits_x_symbol); + exit(-1); + } + + if (soft_output) { + demod_soft_init(&demod_soft); + demod_soft_table_set(&demod_soft, &mod); + demod_soft_alg_set(&demod_soft, soft_exact?EXACT:APPROX); + } else { + demod_hard_init(&demod_hard); + demod_hard_table_set(&demod_hard, modulation); + } + + /* allocate buffers */ + input = malloc(sizeof(char) * num_bits); + if (!input) { + perror("malloc"); + exit(-1); + } + output = malloc(sizeof(char) * num_bits); + if (!output) { + perror("malloc"); + exit(-1); + } + symbols = malloc(sizeof(cf_t) * num_bits / mod.nbits_x_symbol); + if (!symbols) { + perror("malloc"); + exit(-1); + } + + llr = malloc(sizeof(float) * num_bits); + if (!llr) { + perror("malloc"); + exit(-1); + } + + + /* generate random data */ + srand(time(NULL)); + for (i=0;i=0 ? 1 : 0; + } + } else { + demod_hard_demodulate(&demod_hard, symbols, output, num_bits / mod.nbits_x_symbol); + } + + /* check errors */ + for (i=0;inof_symbols; + cf_t *x[MAX_LAYERS]; - cf_t *x[MAX_LAYERS], *d[MAX_CODEWORDS]; /* number of layers equals number of ports */ for (i=0;ipbch_x[i]; } memset(&x[MAX_PORTS_CTRL], 0, sizeof(cf_t*) * (MAX_LAYERS - MAX_PORTS_CTRL)); - /* always one codeword only */ - d[0] = q->pbch_d; - memset(&d[1], 0, sizeof(cf_t*) * (MAX_CODEWORDS - 1)); - /* extract symbols */ if (q->nof_symbols != pbch_get(slot1_symbols, q->pbch_symbols[0], nof_prb, @@ -441,8 +437,14 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce[MAX_PORTS_CTRL], int no INFO("Trying %d TX antennas with %d frames\n", nant, q->frame_idx); - precoding_decode(q->pbch_symbols, q->ce, x, nant, q->nof_symbols, TX_DIVERSITY); - layermap_decode(x, d, nant, 1, q->nof_symbols/nant, TX_DIVERSITY); + /* in conctrol channels, only diversity is supported */ + if (nant == 1) { + /* no need for layer demapping */ + predecoding_single_zf(q->pbch_symbols[0], q->ce[0], q->pbch_d, q->nof_symbols); + } else { + predecoding_diversity_zf(q->pbch_symbols, q->ce, x, nant, q->nof_symbols); + layerdemap_diversity(x, q->pbch_d, nant, q->nof_symbols/nant); + } /* demodulate symbols */ demod_soft_sigma_set(&q->demod, ebno); @@ -482,9 +484,10 @@ void pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *slot1_symbols[MAX_PORTS_CTRL] int i; int nof_bits = 2 * q->nof_symbols; - /* Set pointers for layermapping & precoding */ assert(nof_ports < MAX_PORTS_CTRL); - cf_t *x[MAX_LAYERS], *d[MAX_CODEWORDS]; + + /* Set pointers for layermapping & precoding */ + cf_t *x[MAX_LAYERS]; /* number of layers equals number of ports */ for (i=0;ipbch_d; - memset(&d[1], 0, sizeof(cf_t*) * (MAX_CODEWORDS - 1)); - - if (q->frame_idx == 0) { /* pack MIB */ pbch_mib_pack(mib, q->data); @@ -517,8 +515,12 @@ void pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *slot1_symbols[MAX_PORTS_CTRL] /* layer mapping & precoding */ - layermap_encode(d, x, nof_ports, 1, q->nof_symbols/nof_ports, TX_DIVERSITY); - precoding_encode(x, q->pbch_symbols, nof_ports, q->nof_symbols/nof_ports, TX_DIVERSITY); + if (nof_ports > 1) { + layermap_diversity(q->pbch_d, x, nof_ports, q->nof_symbols/nof_ports); + precoding_diversity(x, q->pbch_symbols, nof_ports, q->nof_symbols/nof_ports); + } else { + memcpy(q->pbch_symbols[0], q->pbch_d, q->nof_symbols * sizeof(cf_t)); + } /* mapping to resource elements */ diff --git a/lte/lib/ratematching/test/CMakeLists.txt b/lte/lib/ratematching/test/CMakeLists.txt new file mode 100644 index 000000000..1c4ded6df --- /dev/null +++ b/lte/lib/ratematching/test/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# 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/. +# + +######################################################################## +# RATEMATCHING TEST +######################################################################## + +ADD_EXECUTABLE(rm_conv_test rm_conv_test.c) +TARGET_LINK_LIBRARIES(rm_conv_test lte) + +ADD_TEST(rm_conv_test_1 rm_conv_test -t 480 -r 1920) +ADD_TEST(rm_conv_test_2 rm_conv_test -t 1920 -r 480) + + + diff --git a/lte/lib/ratematching/test/rm_conv_test.c b/lte/lib/ratematching/test/rm_conv_test.c new file mode 100644 index 000000000..a7d9a47e1 --- /dev/null +++ b/lte/lib/ratematching/test/rm_conv_test.c @@ -0,0 +1,134 @@ +/** + * + * \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 +#include +#include + +#include "lte.h" + +int nof_tx_bits=-1, nof_rx_bits=-1; + +void usage(char *prog) { + printf("Usage: %s -t nof_tx_bits -r nof_rx_bits\n", prog); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "tr")) != -1) { + switch (opt) { + case 't': + nof_tx_bits = atoi(argv[optind]); + break; + case 'r': + nof_rx_bits = atoi(argv[optind]); + break; + default: + usage(argv[0]); + exit(-1); + } + } + if (nof_tx_bits == -1) { + usage(argv[0]); + exit(-1); + } + if (nof_rx_bits == -1) { + usage(argv[0]); + exit(-1); + } +} + +int main(int argc, char **argv) { + int i; + char *bits, *rm_bits; + float *rm_symbols, *unrm_symbols; + int nof_errors; + + parse_args(argc, argv); + + bits = malloc(sizeof(char) * nof_tx_bits); + if (!bits) { + perror("malloc"); + exit(-1); + } + rm_bits = malloc(sizeof(char) * nof_rx_bits); + if (!rm_bits) { + perror("malloc"); + exit(-1); + } + rm_symbols = malloc(sizeof(float) * nof_rx_bits); + if (!rm_symbols) { + perror("malloc"); + exit(-1); + } + unrm_symbols = malloc(sizeof(float) * nof_tx_bits); + if (!unrm_symbols) { + perror("malloc"); + exit(-1); + } + + for (i=0;i 0) != bits[i]) { + nof_errors++; + } + } + if (nof_rx_bits > nof_tx_bits) { + if (nof_errors) { + printf("nof_errors=%d\n", nof_errors); + exit(-1); + } + } + + free(bits); + free(rm_bits); + free(rm_symbols); + free(unrm_symbols); + + printf("Ok\n"); + exit(0); +} diff --git a/lte/lib/scrambling/test/CMakeLists.txt b/lte/lib/scrambling/test/CMakeLists.txt new file mode 100644 index 000000000..bf9709cc5 --- /dev/null +++ b/lte/lib/scrambling/test/CMakeLists.txt @@ -0,0 +1,35 @@ +# +# 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/. +# + +######################################################################## +# SCRAMBLING TEST +######################################################################## + +ADD_EXECUTABLE(scrambling_test scrambling_test.c) +TARGET_LINK_LIBRARIES(scrambling_test lte) + +ADD_TEST(scrambling_pbch_bit scrambling_test -s PBCH -c 50) +ADD_TEST(scrambling_pbch_float scrambling_test -s PBCH -c 50 -f) +ADD_TEST(scrambling_pbch_e_bit scrambling_test -s PBCH -c 50 -e) +ADD_TEST(scrambling_pbch_e_float scrambling_test -s PBCH -c 50 -f -e) + + + diff --git a/lte/lib/scrambling/test/scrambling_test.c b/lte/lib/scrambling/test/scrambling_test.c new file mode 100644 index 000000000..8c4473bc1 --- /dev/null +++ b/lte/lib/scrambling/test/scrambling_test.c @@ -0,0 +1,165 @@ +/** + * + * \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 +#include +#include + +#include "lte.h" + +char *sequence_name = NULL; +bool do_floats = false; +lte_cp_t cp = CPNORM; +int cell_id = -1; + +void usage(char *prog) { + printf("Usage: %s [ef] -c cell_id -s [PBCH, PDSCH, PDCCH, PMCH, PUCCH]\n", prog); + printf("\t -e CP extended [Default CP Normal]\n"); + printf("\t -f scramble floats [Default bits]\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "csef")) != -1) { + switch (opt) { + case 'c': + cell_id = atoi(argv[optind]); + break; + case 'e': + cp = CPEXT; + break; + case 'f': + do_floats = true; + break; + case 's': + sequence_name = argv[optind]; + break; + default: + usage(argv[0]); + exit(-1); + } + } + if (cell_id == -1) { + usage(argv[0]); + exit(-1); + } + if (!sequence_name) { + usage(argv[0]); + exit(-1); + } +} + +int init_sequence(sequence_t *seq, char *name) { + if (!strcmp(name, "PBCH")) { + return sequence_pbch(seq, cp, cell_id); + } else { + fprintf(stderr, "Unsupported sequence name %s\n", name); + return -1; + } +} + + +int main(int argc, char **argv) { + int i; + sequence_t seq; + char *input_b, *scrambled_b; + float *input_f, *scrambled_f; + + parse_args(argc, argv); + + if (init_sequence(&seq, sequence_name) == -1) { + fprintf(stderr, "Error initiating sequence %s\n", sequence_name); + exit(-1); + } + + if (!do_floats) { + input_b = malloc(sizeof(char) * seq.len); + if (!input_b) { + perror("malloc"); + exit(-1); + } + scrambled_b = malloc(sizeof(char) * seq.len); + if (!scrambled_b) { + perror("malloc"); + exit(-1); + } + + for (i=0;i