From de13adbc853a1d52c6bf258e8f3e8ec7a4995ac8 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 25 Jun 2014 09:43:06 +0100 Subject: [PATCH] Using factor of average instead of absolute detection threshold, added fixes for high-speed sequence generation (detection still not supported), added tests for multiplexed PRACH sequences --- lte/phy/include/liblte/phy/prach/prach.h | 4 +- lte/phy/lib/prach/src/prach.c | 17 +++- lte/phy/lib/prach/test/CMakeLists.txt | 7 ++ lte/phy/lib/prach/test/prach_test_multi.c | 114 ++++++++++++++++++++++ 4 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 lte/phy/lib/prach/test/prach_test_multi.c diff --git a/lte/phy/include/liblte/phy/prach/prach.h b/lte/phy/include/liblte/phy/prach/prach.h index 000386f8e..b50e78b0d 100644 --- a/lte/phy/include/liblte/phy/prach/prach.h +++ b/lte/phy/include/liblte/phy/prach/prach.h @@ -36,7 +36,9 @@ #include "liblte/phy/utils/dft.h" typedef _Complex float cf_t; -#define PRACH_DETECT_THRESH 0.3 // Should be a value in [0,1] + +//PRACH detection threshold is PRACH_DETECT_FACTOR*average +#define PRACH_DETECT_FACTOR 10 /** Generation and detection of RACH signals for uplink. * Currently only supports preamble formats 0-3. diff --git a/lte/phy/lib/prach/src/prach.c b/lte/phy/lib/prach/src/prach.c index d88bd4ae8..73b2438a3 100644 --- a/lte/phy/lib/prach/src/prach.c +++ b/lte/phy/lib/prach/src/prach.c @@ -182,7 +182,7 @@ int prach_gen_seqs(prach_t *p) { uint32_t u = 0; uint32_t v = 1; - uint32_t v_max = 0; + int v_max = 0; uint32_t p_ = 0; uint32_t d_u = 0; uint32_t d_start = 0; @@ -238,7 +238,9 @@ int prach_gen_seqs(prach_t *p) N_neg_shift = N_shift; } v_max = N_shift*N_group + N_neg_shift - 1; - + if(v_max < 0){ + v_max = 0; + } }else{ // Normal cell if(0 == p->N_cs){ @@ -253,7 +255,11 @@ int prach_gen_seqs(prach_t *p) // Shift root and add to set if(p->hs){ - C_v = d_start*floor(v/N_shift) + (v % N_shift)*p->N_cs; + if(N_shift==0){ + C_v = 0; + }else{ + C_v = d_start*floor(v/N_shift) + (v % N_shift)*p->N_cs; + } }else{ C_v = v*p->N_cs; } @@ -439,6 +445,7 @@ int prach_detect(prach_t *p, memset(p->corr_spec, 0, sizeof(cf_t)*p->N_zc); memset(p->corr, 0, sizeof(float)*p->N_zc); float corr_max = 0; + float corr_ave = 0; cf_t *root_spec = p->dft_seqs[p->root_seqs_idx[i]]; @@ -451,7 +458,9 @@ int prach_detect(prach_t *p, float norm = sqrtf(p->N_zc); for(int j=0;jN_zc;j++){ p->corr[j] = cabsf(p->corr_spec[j])/norm; + corr_ave += p->corr[j]; } + corr_ave /= p->N_zc; uint32_t winsize = 0; if(p->N_cs != 0){ @@ -469,7 +478,7 @@ int prach_detect(prach_t *p, corr_max = p->corr[k]; } } - if(corr_max > PRACH_DETECT_THRESH){ + if(corr_max > PRACH_DETECT_FACTOR*corr_ave){ indices[*n_indices] = (i*n_wins)+j; (*n_indices)++; } diff --git a/lte/phy/lib/prach/test/CMakeLists.txt b/lte/phy/lib/prach/test/CMakeLists.txt index 2122b1f0f..2edb84de3 100644 --- a/lte/phy/lib/prach/test/CMakeLists.txt +++ b/lte/phy/lib/prach/test/CMakeLists.txt @@ -50,5 +50,12 @@ ADD_TEST(prach_zc0 prach_test -z 0) ADD_TEST(prach_zc2 prach_test -z 2) ADD_TEST(prach_zc3 prach_test -z 3) +ADD_EXECUTABLE(prach_test_multi prach_test_multi.c) +TARGET_LINK_LIBRARIES(prach_test_multi lte_phy) +ADD_TEST(prach_test_multi prach_test_multi) +ADD_TEST(prach_test_multi_n32 prach_test_multi -n 32) +ADD_TEST(prach_test_multi_n16 prach_test_multi -n 16) +ADD_TEST(prach_test_multi_n8 prach_test_multi -n 8) +ADD_TEST(prach_test_multi_n4 prach_test_multi -n 4) diff --git a/lte/phy/lib/prach/test/prach_test_multi.c b/lte/phy/lib/prach/test/prach_test_multi.c new file mode 100644 index 000000000..b6f9de9ce --- /dev/null +++ b/lte/phy/lib/prach/test/prach_test_multi.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "liblte/phy/prach/prach.h" + +#define MAX_LEN 70176 +typedef _Complex float cf_t; + +uint32_t N_ifft_ul = 128; +uint32_t preamble_format = 0; +uint32_t root_seq_idx = 0; +uint32_t zero_corr_zone = 1; +uint32_t n_seqs = 64; + +void usage(char *prog) { + printf("Usage: %s\n", prog); + printf("\t-N Uplink IFFT size [Default 128]\n"); + printf("\t-f Preamble format [Default 0]\n"); + printf("\t-r Root sequence index [Default 0]\n"); + printf("\t-z Zero correlation zone config [Default 1]\n"); + printf("\t-n Number of sequences used for each test [Default 64]\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "Nfrzn")) != -1) { + switch (opt) { + case 'N': + N_ifft_ul = atoi(argv[optind]); + break; + case 'f': + preamble_format = atoi(argv[optind]); + break; + case 'r': + root_seq_idx = atoi(argv[optind]); + break; + case 'z': + zero_corr_zone = atoi(argv[optind]); + break; + case 'n': + n_seqs = atoi(argv[optind]); + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +int main(int argc, char **argv) { + parse_args(argc, argv); + + prach_t *p = (prach_t*)malloc(sizeof(prach_t)); + + bool high_speed_flag = false; + + cf_t preamble[MAX_LEN]; + memset(preamble, 0, sizeof(cf_t)*MAX_LEN); + cf_t preamble_sum[MAX_LEN]; + memset(preamble_sum, 0, sizeof(cf_t)*MAX_LEN); + + prach_init(p, + N_ifft_ul, + preamble_format, + root_seq_idx, + high_speed_flag, + zero_corr_zone); + + uint32_t seq_index = 0; + uint32_t frequency_offset = 0; + + uint32_t indices[64]; + uint32_t n_indices = 0; + for(int i=0;i<64;i++) + indices[i] = 0; + + for(seq_index=0;seq_indexN_cp+p->N_seq;i++) + { + preamble_sum[i] += preamble[i]; + } + } + + uint32_t prach_len = p->N_seq; + if(preamble_format == 2 || preamble_format == 3) + prach_len /= 2; + prach_detect(p, 0, &preamble_sum[p->N_cp], prach_len, indices, &n_indices); + + if(n_indices != n_seqs) + return -1; + + for(int i=0;i