- Calculate the FFT of the PRACH on demand.

- Fixed a PRACH test that was failing with ASAN.
This commit is contained in:
faluco 2020-09-17 18:41:00 +02:00 committed by faluco
parent b6bbe8761a
commit b892da0294
3 changed files with 45 additions and 32 deletions

View File

@ -75,6 +75,7 @@ typedef struct SRSLTE_API {
// Generated tables
cf_t seqs[64][839]; // Our set of 64 preamble sequences
cf_t dft_seqs[64][839]; // DFT-precoded seqs
uint64_t dft_gen_bitmap; // Bitmap where each bit Indicates if the dft has been generated for sequence i.
uint32_t root_seqs_idx[64]; // Indices of root seqs in seqs table
uint32_t N_roots; // Number of root sequences used in this configuration
cf_t* td_signals[64];
@ -134,7 +135,6 @@ typedef struct {
bool enable_freq_domain_offset_calc;
} srslte_prach_cfg_t;
typedef struct SRSLTE_API {
uint32_t f;
uint32_t t0;
@ -217,14 +217,14 @@ SRSLTE_API int srslte_prach_free(srslte_prach_t* p);
SRSLTE_API int srslte_prach_print_seqs(srslte_prach_t* p);
SRSLTE_API int srslte_prach_process(srslte_prach_t* p,
cf_t* signal,
uint32_t* indices,
float* t_offsets,
float* peak_to_avg,
uint32_t* n_indices,
int cancellation_idx,
uint32_t begin,
uint32_t sig_len);
SRSLTE_API int srslte_prach_process(srslte_prach_t* p,
cf_t* signal,
uint32_t* indices,
float* t_offsets,
float* peak_to_avg,
uint32_t* n_indices,
int cancellation_idx,
uint32_t begin,
uint32_t sig_len);
#endif // SRSLTE_PRACH_H

View File

@ -20,6 +20,7 @@
*/
#include "srslte/srslte.h"
#include <assert.h>
#include <math.h>
#include <string.h>
@ -222,6 +223,20 @@ void print(void* d, uint32_t size, uint32_t len, char* file_str)
fclose(f);
}
/// Calculates the FFT of the specified sequence index if not previously done and returns a pointer to the result.
static cf_t* get_precoded_dft(srslte_prach_t* p, uint32_t idx)
{
assert(idx < 64 && "Invalid idx value");
// Generate FFT for this sequence if it does not exist yet.
uint64_t gen_mask = (uint64_t)1 << idx;
if (!(p->dft_gen_bitmap & gen_mask)) {
srslte_dft_run(&p->zc_fft, p->seqs[idx], p->dft_seqs[idx]);
p->dft_gen_bitmap |= gen_mask;
}
return p->dft_seqs[idx];
}
int srslte_prach_gen_seqs(srslte_prach_t* p)
{
uint32_t u = 0;
@ -410,6 +425,7 @@ int srslte_prach_set_cell_(srslte_prach_t* p,
p->detect_factor = PRACH_DETECT_FACTOR;
p->num_ra_preambles = cfg->num_ra_preambles;
p->successive_cancellation = cfg->enable_successive_cancellation;
p->dft_gen_bitmap = 0;
if (p->successive_cancellation && cfg->zero_corr_zone != 0) {
printf("successive cancellation only currently supported with zero_correlation_zone_config of 0 - disabling\n");
p->successive_cancellation = false;
@ -464,10 +480,6 @@ int srslte_prach_set_cell_(srslte_prach_t* p,
if (p->num_ra_preambles < 4 || p->num_ra_preambles > p->N_roots) {
p->num_ra_preambles = p->N_roots;
}
// Generate sequence FFTs
for (int i = 0; i < N_SEQS; i++) {
srslte_dft_run(&p->zc_fft, p->seqs[i], p->dft_seqs[i]);
}
// Create our FFT objects and buffers
p->N_ifft_ul = N_ifft_ul;
@ -540,7 +552,7 @@ int srslte_prach_gen(srslte_prach_t* p, uint32_t seq_index, uint32_t freq_offset
// Map dft-precoded sequence to ifft bins
memset(p->ifft_in, 0, begin * sizeof(cf_t));
memcpy(&p->ifft_in[begin], p->dft_seqs[seq_index], p->N_zc * sizeof(cf_t));
memcpy(&p->ifft_in[begin], get_precoded_dft(p, seq_index), p->N_zc * sizeof(cf_t));
memset(&p->ifft_in[begin + p->N_zc], 0, (p->N_ifft_prach - begin - p->N_zc) * sizeof(cf_t));
srslte_dft_run(&p->ifft, p->ifft_in, p->ifft_out);
@ -581,7 +593,8 @@ int srslte_prach_detect(srslte_prach_t* p,
void srslte_prach_cancellation(srslte_prach_t* p)
{
srslte_vec_cf_zero(p->sub, p->N_zc * 2);
srslte_vec_cf_copy(p->sub, &p->dft_seqs[p->root_seqs_idx[p->prach_cancel.idx]][0], p->N_zc);
srslte_vec_cf_copy(p->sub, get_precoded_dft(p, p->root_seqs_idx[p->prach_cancel.idx]), p->N_zc);
srslte_vec_prod_ccc(p->sub, p->prach_cancel.phase_array, p->sub, p->N_zc);
#ifdef PRACH_CANCELLATION_HARD
srslte_vec_prod_conj_ccc(p->prach_bins, p->sub, p->corr_spec, p->N_zc);
@ -651,7 +664,7 @@ int srslte_prach_process(srslte_prach_t* p,
srslte_vec_cf_zero(p->cross, p->N_zc);
srslte_vec_cf_zero(p->corr_freq, p->N_zc);
for (int i = 0; i < p->num_ra_preambles; i++) {
cf_t* root_spec = p->dft_seqs[p->root_seqs_idx[i]];
cf_t* root_spec = get_precoded_dft(p, p->root_seqs_idx[i]);
srslte_vec_prod_conj_ccc(p->prach_bins, root_spec, p->corr_spec, p->N_zc);

View File

@ -110,35 +110,35 @@ void parse_args(int argc, char** argv)
}
}
// this function staggers power and phase of the different PRACH signals for more realisitc testing
void stagger_prach_powers(srslte_prach_t prach, cf_t *preamble, cf_t* preamble_sum, int freq_offset, int n_seqs, int *offsets) {
void stagger_prach_powers(srslte_prach_t *prach, cf_t *preamble, cf_t* preamble_sum, int freq_offset, int n_seqs, int *offsets) {
for (int seq_index = 0; seq_index < n_seqs; seq_index++) {
srslte_prach_gen(&prach, seq_index, freq_offset, preamble);
srslte_prach_gen(prach, seq_index, freq_offset, preamble);
if (seq_index == 0) {
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.5), preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_cfc(preamble, 1, preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.5), preamble, prach->N_cp + prach->N_seq);
srslte_vec_sc_prod_cfc(preamble, 1, preamble, prach->N_cp + prach->N_seq);
}
if (seq_index == 1) {
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 1), preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.8, preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 1), preamble, prach->N_cp + prach->N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.8, preamble, prach->N_cp + prach->N_seq);
}
if (seq_index == 2) {
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.1), preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.05, preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.1), preamble, prach->N_cp + prach->N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.05, preamble, prach->N_cp + prach->N_seq);
}
if (seq_index == 3) {
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.9), preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.7, preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.9), preamble, prach->N_cp + prach->N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.7, preamble, prach->N_cp + prach->N_seq);
}
if (seq_index == 4) {
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.3), preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.15, preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_ccc(preamble, cexpf(_Complex_I * 0.3), preamble, prach->N_cp + prach->N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.15, preamble, prach->N_cp + prach->N_seq);
}
if (seq_index == 5) {
srslte_vec_sc_prod_cfc(preamble, 0.15, preamble, prach.N_cp + prach.N_seq);
srslte_vec_sc_prod_cfc(preamble, 0.15, preamble, prach->N_cp + prach->N_seq);
}
int off = (offset == -1) ? offsets[seq_index] : offset;
for (int i = 0; i < prach.N_cp + prach.N_seq; i++) {
for (int i = 0; i < prach->N_cp + prach->N_seq; i++) {
preamble_sum[i + off] += preamble[i];
}
}
@ -209,7 +209,7 @@ int main(int argc, char** argv)
srslte_prach_set_detect_factor(&prach, 10);
if (stagger_prach_power_and_phase) {
stagger_prach_powers(prach, preamble, preamble_sum, prach_cfg.freq_offset, n_seqs, offsets);
stagger_prach_powers(&prach, preamble, preamble_sum, prach_cfg.freq_offset, n_seqs, offsets);
} else {
for (seq_index = 0; seq_index < n_seqs; seq_index++) {
srslte_prach_gen(&prach, seq_index, prach_cfg.freq_offset, preamble);