Skip to content

Commit 3eae95d

Browse files
srs-codebotasaezper
authored andcommitted
Merge remote-tracking branch 'origin/next' into HEAD
2 parents fa56836 + 4eb990c commit 3eae95d

File tree

23 files changed

+402
-10
lines changed

23 files changed

+402
-10
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ option(FORCE_32BIT "Add flags to force 32 bit compilation" OFF)
9898
option(ENABLE_SRSLOG_TRACING "Enable event tracing using srslog" OFF)
9999
option(ASSERTS_ENABLED "Enable srsRAN asserts" ON)
100100
option(STOP_ON_WARNING "Interrupt application on warning" OFF)
101+
option(ENABLE_WERROR "Stop compilation on errors" ON)
101102

102103
option(ENABLE_ALL_TEST "Enable all unit/component test" OFF)
103104

@@ -537,7 +538,7 @@ if("Ninja" STREQUAL ${CMAKE_GENERATOR})
537538
endif()
538539

539540
# Add -Werror to C/C++ flags for newer compilers
540-
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
541+
if(ENABLE_WERROR AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
541542
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
542543
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
543544
endif()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
*
3+
* \section COPYRIGHT
4+
*
5+
* Copyright 2013-2023 Software Radio Systems Limited
6+
*
7+
* By using this file, you agree to the terms and conditions set
8+
* forth in the LICENSE file which can be found at the top level of
9+
* the distribution.
10+
*
11+
*/
12+
13+
#ifndef SRSRAN_CEDRON_FREQ_ESTIMATOR_H
14+
#define SRSRAN_CEDRON_FREQ_ESTIMATOR_H
15+
16+
#include "srsran/config.h"
17+
#include "srsran/phy/common/phy_common.h"
18+
#include <stdio.h>
19+
20+
typedef struct {
21+
// DFT
22+
void* in; // Input buffer
23+
void* out; // Output buffer
24+
void* p; // DFT plan
25+
cf_t* X; // Output buffer as cf_t*
26+
int init_size;
27+
int fft_size; // Currently used FFT size
28+
29+
} srsran_cedron_freq_est_t;
30+
31+
SRSRAN_API int srsran_cedron_freq_est_init(srsran_cedron_freq_est_t* q, uint32_t nof_prbs);
32+
33+
SRSRAN_API void srsran_cedron_freq_est_free(srsran_cedron_freq_est_t* q);
34+
35+
SRSRAN_API int srsran_cedron_freq_est_replan_c(srsran_cedron_freq_est_t* q, int new_dft_points);
36+
37+
SRSRAN_API float srsran_cedron_freq_estimate(srsran_cedron_freq_est_t* q, const cf_t* x, int len);
38+
39+
#endif // SRSRAN_CEDRON_FREQ_ESTIMATOR_H

lib/include/srsran/phy/ch_estimation/chest_ul.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include "srsran/config.h"
4040

41+
#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
4142
#include "srsran/phy/ch_estimation/chest_common.h"
4243
#include "srsran/phy/ch_estimation/refsignal_ul.h"
4344
#include "srsran/phy/common/phy_common.h"
@@ -85,6 +86,7 @@ typedef struct {
8586

8687
srsran_interp_linsrsran_vec_t srsran_interp_linvec;
8788

89+
srsran_cedron_freq_est_t srsran_cedron_freq_est;
8890
} srsran_chest_ul_t;
8991

9092
SRSRAN_API int srsran_chest_ul_init(srsran_chest_ul_t* q, uint32_t max_prb);

lib/include/srsran/phy/phch/pucch_cfg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ typedef struct SRSRAN_API {
7878
float threshold_data_valid_format3;
7979
float threshold_dmrs_detection;
8080
bool meas_ta_en;
81+
bool use_cedron_alg;
8182

8283
// PUCCH configuration generated during a call to encode/decode
8384
srsran_pucch_format_t format;

lib/include/srsran/phy/phch/pusch_cfg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ typedef struct SRSRAN_API {
8181

8282
bool meas_epre_en;
8383
bool meas_ta_en;
84+
bool use_cedron_alg;
8485
bool meas_evm_en;
8586

8687
} srsran_pusch_cfg_t;

lib/include/srsran/radio/channel_mapping.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <list>
2727
#include <map>
2828
#include <mutex>
29+
#include <string>
2930

3031
namespace srsran {
3132

lib/include/srsran/srsran.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern "C" {
4646
#include "srsran/phy/common/timestamp.h"
4747
#include "srsran/phy/utils/phy_logger.h"
4848

49+
#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
4950
#include "srsran/phy/ch_estimation/chest_dl.h"
5051
#include "srsran/phy/ch_estimation/chest_ul.h"
5152
#include "srsran/phy/ch_estimation/csi_rs.h"

lib/src/common/band_helper.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ double srsran_band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_pr
124124
// TODO: add offset_to_carrier
125125
double abs_freq_point_a_freq = nr_arfcn_to_freq(freq_point_a_arfcn);
126126
return abs_freq_point_a_freq +
127-
(nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) *
127+
(1.0 * nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) *
128128
SRSRAN_NRE);
129129
}
130130

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/**
2+
*
3+
* \section COPYRIGHT
4+
*
5+
* Copyright 2013-2023 Software Radio Systems Limited
6+
*
7+
* By using this file, you agree to the terms and conditions set
8+
* forth in the LICENSE file which can be found at the top level of
9+
* the distribution.
10+
*
11+
*/
12+
13+
#include <complex.h>
14+
#include <math.h>
15+
#include <stdio.h>
16+
17+
#include "srsran/config.h"
18+
#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
19+
#include "srsran/phy/utils/vector_simd.h"
20+
#include "srsran/srsran.h"
21+
#include <fftw3.h>
22+
23+
static pthread_mutex_t freq_est_fft_mutex = PTHREAD_MUTEX_INITIALIZER;
24+
25+
int srsran_cedron_freq_est_init(srsran_cedron_freq_est_t* q, uint32_t nof_prbs)
26+
{
27+
int ret = SRSRAN_ERROR_INVALID_INPUTS;
28+
int N = SRSRAN_MAX_PRB * SRSRAN_NRE;
29+
if (q != NULL) {
30+
bzero(q, sizeof(srsran_cedron_freq_est_t));
31+
32+
q->init_size = N;
33+
q->fft_size = nof_prbs * SRSRAN_NRE;
34+
q->in = fftwf_malloc(sizeof(fftwf_complex) * N);
35+
if (!q->in) {
36+
perror("fftwf_malloc");
37+
goto clean_exit;
38+
}
39+
q->out = fftwf_malloc(sizeof(fftwf_complex) * N);
40+
if (!q->out) {
41+
perror("fftwf_malloc");
42+
goto clean_exit;
43+
}
44+
45+
pthread_mutex_lock(&freq_est_fft_mutex);
46+
q->p = fftwf_plan_dft_1d(q->fft_size, q->in, q->out, FFTW_FORWARD, 0U);
47+
pthread_mutex_unlock(&freq_est_fft_mutex);
48+
49+
if (!q->p) {
50+
perror("fftwf_plan_dft_1d");
51+
goto clean_exit;
52+
}
53+
q->X = q->out;
54+
}
55+
56+
ret = SRSRAN_SUCCESS;
57+
58+
clean_exit:
59+
if (ret != SRSRAN_SUCCESS) {
60+
srsran_cedron_freq_est_free(q);
61+
}
62+
return ret;
63+
}
64+
65+
void srsran_cedron_freq_est_free(srsran_cedron_freq_est_t* q)
66+
{
67+
if (!q) {
68+
return;
69+
}
70+
pthread_mutex_lock(&freq_est_fft_mutex);
71+
if (q->in) {
72+
fftwf_free(q->in);
73+
}
74+
if (q->out) {
75+
fftwf_free(q->out);
76+
}
77+
if (q->p) {
78+
fftwf_destroy_plan(q->p);
79+
q->p = NULL;
80+
}
81+
q->X = NULL;
82+
pthread_mutex_unlock(&freq_est_fft_mutex);
83+
bzero(q, sizeof(srsran_cedron_freq_est_t));
84+
}
85+
86+
int srsran_cedron_freq_est_replan_c(srsran_cedron_freq_est_t* q, int new_dft_points)
87+
{
88+
// No change in size, skip re-planning
89+
if (q->fft_size == new_dft_points) {
90+
return 0;
91+
}
92+
93+
pthread_mutex_lock(&freq_est_fft_mutex);
94+
if (q->p) {
95+
fftwf_destroy_plan(q->p);
96+
q->p = NULL;
97+
}
98+
q->p = fftwf_plan_dft_1d(new_dft_points, q->in, q->out, FFTW_FORWARD, FFTW_MEASURE);
99+
pthread_mutex_unlock(&freq_est_fft_mutex);
100+
101+
if (!q->p) {
102+
return -1;
103+
}
104+
q->fft_size = new_dft_points;
105+
return 0;
106+
}
107+
108+
float srsran_cedron_freq_estimate(srsran_cedron_freq_est_t* q, const cf_t* x, int N)
109+
{
110+
/*
111+
* Three Bin Exact Frequency Formulas for a Pure Complex Tone in a DFT
112+
* Cedron Dawg
113+
* https://www.dsprelated.com/showarticle/1043.php
114+
*/
115+
const float TWOPI = 2.0f * (float)M_PI;
116+
cf_t Z[3], R1, num, den, ratio;
117+
float alpha, f_est;
118+
int32_t k_max;
119+
120+
if (N != q->fft_size) {
121+
srsran_cedron_freq_est_replan_c(q, N);
122+
}
123+
124+
memcpy(q->in, x, sizeof(cf_t) * N);
125+
fftwf_execute(q->p);
126+
127+
k_max = srsran_vec_max_ci_simd(q->X, N);
128+
if (k_max == 0) {
129+
Z[0] = q->X[N - 1];
130+
Z[1] = q->X[0];
131+
Z[2] = q->X[1];
132+
} else if (k_max == N - 1) {
133+
Z[0] = q->X[N - 2];
134+
Z[1] = q->X[N - 1];
135+
Z[2] = q->X[0];
136+
} else {
137+
Z[0] = q->X[k_max - 1];
138+
Z[1] = q->X[k_max];
139+
Z[2] = q->X[k_max + 1];
140+
}
141+
142+
R1 = cexpf(-1.0 * _Complex_I * TWOPI / N);
143+
num = -R1 * Z[0] + (1 + R1) * Z[1] - Z[2];
144+
den = -Z[0] + (1 + R1) * Z[1] - R1 * Z[2];
145+
srsran_vec_div_ccc_simd(&num, &den, &ratio, 1);
146+
alpha = atan2f(__imag__(ratio), __real__(ratio));
147+
148+
if (k_max > floor(N / 2)) {
149+
k_max = -(N - k_max);
150+
}
151+
f_est = 1.0 * k_max / N + alpha * M_1_PI * 0.5f;
152+
153+
return -f_est;
154+
}

lib/src/phy/ch_estimation/chest_ul.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <strings.h>
2929

3030
#include "srsran/config.h"
31+
#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
3132
#include "srsran/phy/ch_estimation/chest_ul.h"
3233
#include "srsran/phy/dft/dft_precoding.h"
3334
#include "srsran/phy/utils/convolution.h"
@@ -98,6 +99,11 @@ int srsran_chest_ul_init(srsran_chest_ul_t* q, uint32_t max_prb)
9899
ERROR("Error allocating memory for pregenerated signals");
99100
goto clean_exit;
100101
}
102+
103+
if (srsran_cedron_freq_est_init(&q->srsran_cedron_freq_est, max_prb)) {
104+
ERROR("Error initializing cedron freq estimation algorithm.");
105+
goto clean_exit;
106+
}
101107
}
102108

103109
ret = SRSRAN_SUCCESS;
@@ -117,6 +123,7 @@ void srsran_chest_ul_free(srsran_chest_ul_t* q)
117123
free(q->tmp_noise);
118124
}
119125
srsran_interp_linear_vector_free(&q->srsran_interp_linvec);
126+
srsran_cedron_freq_est_free(&q->srsran_cedron_freq_est);
120127

121128
if (q->pilot_estimates) {
122129
free(q->pilot_estimates);
@@ -293,6 +300,7 @@ static void chest_ul_estimate(srsran_chest_ul_t* q,
293300
uint32_t nrefs_sym,
294301
uint32_t stride,
295302
bool meas_ta_en,
303+
bool use_cedron_alg,
296304
bool write_estimates,
297305
uint32_t n_prb[SRSRAN_NOF_SLOTS_PER_SF],
298306
srsran_chest_ul_res_t* res)
@@ -310,7 +318,13 @@ static void chest_ul_estimate(srsran_chest_ul_t* q,
310318
float ta_err = 0.0f;
311319
if (meas_ta_en) {
312320
for (int i = 0; i < nslots; i++) {
313-
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[i * nrefs_sym], nrefs_sym) / nslots;
321+
if (use_cedron_alg) {
322+
ta_err +=
323+
srsran_cedron_freq_estimate(&q->srsran_cedron_freq_est, &q->pilot_estimates[i * nrefs_sym], nrefs_sym) /
324+
nslots;
325+
} else {
326+
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[i * nrefs_sym], nrefs_sym) / nslots;
327+
}
314328
}
315329
}
316330

@@ -412,7 +426,8 @@ int srsran_chest_ul_estimate_pusch(srsran_chest_ul_t* q,
412426
nrefs_sf);
413427

414428
// Estimate
415-
chest_ul_estimate(q, SRSRAN_NOF_SLOTS_PER_SF, nrefs_sym, 1, cfg->meas_ta_en, true, cfg->grant.n_prb, res);
429+
chest_ul_estimate(
430+
q, SRSRAN_NOF_SLOTS_PER_SF, nrefs_sym, 1, cfg->meas_ta_en, cfg->use_cedron_alg, true, cfg->grant.n_prb, res);
416431

417432
return 0;
418433
}
@@ -515,8 +530,14 @@ int srsran_chest_ul_estimate_pucch(srsran_chest_ul_t* q,
515530
float ta_err = 0.0f;
516531
for (int ns = 0; ns < SRSRAN_NOF_SLOTS_PER_SF; ns++) {
517532
for (int i = 0; i < n_rs; i++) {
518-
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[(i + ns * n_rs) * SRSRAN_NRE], SRSRAN_NRE) /
519-
(float)(SRSRAN_NOF_SLOTS_PER_SF * n_rs);
533+
if (cfg->use_cedron_alg) {
534+
ta_err += srsran_cedron_freq_estimate(
535+
&q->srsran_cedron_freq_est, &q->pilot_estimates[(i + ns * n_rs) * SRSRAN_NRE], SRSRAN_NRE) /
536+
(float)(SRSRAN_NOF_SLOTS_PER_SF * n_rs);
537+
} else {
538+
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[(i + ns * n_rs) * SRSRAN_NRE], SRSRAN_NRE) /
539+
(float)(SRSRAN_NOF_SLOTS_PER_SF * n_rs);
540+
}
520541
}
521542
}
522543

@@ -620,7 +641,7 @@ int srsran_chest_ul_estimate_srs(srsran_chest_ul_t* q,
620641

621642
// Estimate
622643
uint32_t n_prb[2] = {};
623-
chest_ul_estimate(q, 1, n_srs_re, 1, true, false, n_prb, res);
644+
chest_ul_estimate(q, 1, n_srs_re, 1, true, false, false, n_prb, res);
624645

625646
return SRSRAN_SUCCESS;
626647
}

0 commit comments

Comments
 (0)