Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/next' into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
srs-codebot authored and asaezper committed Nov 23, 2023
2 parents fa56836 + 4eb990c commit 3eae95d
Show file tree
Hide file tree
Showing 23 changed files with 402 additions and 10 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ option(FORCE_32BIT "Add flags to force 32 bit compilation" OFF)
option(ENABLE_SRSLOG_TRACING "Enable event tracing using srslog" OFF)
option(ASSERTS_ENABLED "Enable srsRAN asserts" ON)
option(STOP_ON_WARNING "Interrupt application on warning" OFF)
option(ENABLE_WERROR "Stop compilation on errors" ON)

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

Expand Down Expand Up @@ -537,7 +538,7 @@ if("Ninja" STREQUAL ${CMAKE_GENERATOR})
endif()

# Add -Werror to C/C++ flags for newer compilers
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
if(ENABLE_WERROR AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
Expand Down
39 changes: 39 additions & 0 deletions lib/include/srsran/phy/ch_estimation/cedron_freq_estimator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2023 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#ifndef SRSRAN_CEDRON_FREQ_ESTIMATOR_H
#define SRSRAN_CEDRON_FREQ_ESTIMATOR_H

#include "srsran/config.h"
#include "srsran/phy/common/phy_common.h"
#include <stdio.h>

typedef struct {
// DFT
void* in; // Input buffer
void* out; // Output buffer
void* p; // DFT plan
cf_t* X; // Output buffer as cf_t*
int init_size;
int fft_size; // Currently used FFT size

} srsran_cedron_freq_est_t;

SRSRAN_API int srsran_cedron_freq_est_init(srsran_cedron_freq_est_t* q, uint32_t nof_prbs);

SRSRAN_API void srsran_cedron_freq_est_free(srsran_cedron_freq_est_t* q);

SRSRAN_API int srsran_cedron_freq_est_replan_c(srsran_cedron_freq_est_t* q, int new_dft_points);

SRSRAN_API float srsran_cedron_freq_estimate(srsran_cedron_freq_est_t* q, const cf_t* x, int len);

#endif // SRSRAN_CEDRON_FREQ_ESTIMATOR_H
2 changes: 2 additions & 0 deletions lib/include/srsran/phy/ch_estimation/chest_ul.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#include "srsran/config.h"

#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
#include "srsran/phy/ch_estimation/chest_common.h"
#include "srsran/phy/ch_estimation/refsignal_ul.h"
#include "srsran/phy/common/phy_common.h"
Expand Down Expand Up @@ -85,6 +86,7 @@ typedef struct {

srsran_interp_linsrsran_vec_t srsran_interp_linvec;

srsran_cedron_freq_est_t srsran_cedron_freq_est;
} srsran_chest_ul_t;

SRSRAN_API int srsran_chest_ul_init(srsran_chest_ul_t* q, uint32_t max_prb);
Expand Down
1 change: 1 addition & 0 deletions lib/include/srsran/phy/phch/pucch_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct SRSRAN_API {
float threshold_data_valid_format3;
float threshold_dmrs_detection;
bool meas_ta_en;
bool use_cedron_alg;

// PUCCH configuration generated during a call to encode/decode
srsran_pucch_format_t format;
Expand Down
1 change: 1 addition & 0 deletions lib/include/srsran/phy/phch/pusch_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ typedef struct SRSRAN_API {

bool meas_epre_en;
bool meas_ta_en;
bool use_cedron_alg;
bool meas_evm_en;

} srsran_pusch_cfg_t;
Expand Down
1 change: 1 addition & 0 deletions lib/include/srsran/radio/channel_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <list>
#include <map>
#include <mutex>
#include <string>

namespace srsran {

Expand Down
1 change: 1 addition & 0 deletions lib/include/srsran/srsran.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern "C" {
#include "srsran/phy/common/timestamp.h"
#include "srsran/phy/utils/phy_logger.h"

#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
#include "srsran/phy/ch_estimation/chest_dl.h"
#include "srsran/phy/ch_estimation/chest_ul.h"
#include "srsran/phy/ch_estimation/csi_rs.h"
Expand Down
2 changes: 1 addition & 1 deletion lib/src/common/band_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ double srsran_band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_pr
// TODO: add offset_to_carrier
double abs_freq_point_a_freq = nr_arfcn_to_freq(freq_point_a_arfcn);
return abs_freq_point_a_freq +
(nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) *
(1.0 * nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) *
SRSRAN_NRE);
}

Expand Down
154 changes: 154 additions & 0 deletions lib/src/phy/ch_estimation/cedron_freq_estimator.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2023 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#include <complex.h>
#include <math.h>
#include <stdio.h>

#include "srsran/config.h"
#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
#include "srsran/phy/utils/vector_simd.h"
#include "srsran/srsran.h"
#include <fftw3.h>

static pthread_mutex_t freq_est_fft_mutex = PTHREAD_MUTEX_INITIALIZER;

int srsran_cedron_freq_est_init(srsran_cedron_freq_est_t* q, uint32_t nof_prbs)
{
int ret = SRSRAN_ERROR_INVALID_INPUTS;
int N = SRSRAN_MAX_PRB * SRSRAN_NRE;
if (q != NULL) {
bzero(q, sizeof(srsran_cedron_freq_est_t));

q->init_size = N;
q->fft_size = nof_prbs * SRSRAN_NRE;
q->in = fftwf_malloc(sizeof(fftwf_complex) * N);
if (!q->in) {
perror("fftwf_malloc");
goto clean_exit;
}
q->out = fftwf_malloc(sizeof(fftwf_complex) * N);
if (!q->out) {
perror("fftwf_malloc");
goto clean_exit;
}

pthread_mutex_lock(&freq_est_fft_mutex);
q->p = fftwf_plan_dft_1d(q->fft_size, q->in, q->out, FFTW_FORWARD, 0U);
pthread_mutex_unlock(&freq_est_fft_mutex);

if (!q->p) {
perror("fftwf_plan_dft_1d");
goto clean_exit;
}
q->X = q->out;
}

ret = SRSRAN_SUCCESS;

clean_exit:
if (ret != SRSRAN_SUCCESS) {
srsran_cedron_freq_est_free(q);
}
return ret;
}

void srsran_cedron_freq_est_free(srsran_cedron_freq_est_t* q)
{
if (!q) {
return;
}
pthread_mutex_lock(&freq_est_fft_mutex);
if (q->in) {
fftwf_free(q->in);
}
if (q->out) {
fftwf_free(q->out);
}
if (q->p) {
fftwf_destroy_plan(q->p);
q->p = NULL;
}
q->X = NULL;
pthread_mutex_unlock(&freq_est_fft_mutex);
bzero(q, sizeof(srsran_cedron_freq_est_t));
}

int srsran_cedron_freq_est_replan_c(srsran_cedron_freq_est_t* q, int new_dft_points)
{
// No change in size, skip re-planning
if (q->fft_size == new_dft_points) {
return 0;
}

pthread_mutex_lock(&freq_est_fft_mutex);
if (q->p) {
fftwf_destroy_plan(q->p);
q->p = NULL;
}
q->p = fftwf_plan_dft_1d(new_dft_points, q->in, q->out, FFTW_FORWARD, FFTW_MEASURE);
pthread_mutex_unlock(&freq_est_fft_mutex);

if (!q->p) {
return -1;
}
q->fft_size = new_dft_points;
return 0;
}

float srsran_cedron_freq_estimate(srsran_cedron_freq_est_t* q, const cf_t* x, int N)
{
/*
* Three Bin Exact Frequency Formulas for a Pure Complex Tone in a DFT
* Cedron Dawg
* https://www.dsprelated.com/showarticle/1043.php
*/
const float TWOPI = 2.0f * (float)M_PI;
cf_t Z[3], R1, num, den, ratio;
float alpha, f_est;
int32_t k_max;

if (N != q->fft_size) {
srsran_cedron_freq_est_replan_c(q, N);
}

memcpy(q->in, x, sizeof(cf_t) * N);
fftwf_execute(q->p);

k_max = srsran_vec_max_ci_simd(q->X, N);
if (k_max == 0) {
Z[0] = q->X[N - 1];
Z[1] = q->X[0];
Z[2] = q->X[1];
} else if (k_max == N - 1) {
Z[0] = q->X[N - 2];
Z[1] = q->X[N - 1];
Z[2] = q->X[0];
} else {
Z[0] = q->X[k_max - 1];
Z[1] = q->X[k_max];
Z[2] = q->X[k_max + 1];
}

R1 = cexpf(-1.0 * _Complex_I * TWOPI / N);
num = -R1 * Z[0] + (1 + R1) * Z[1] - Z[2];
den = -Z[0] + (1 + R1) * Z[1] - R1 * Z[2];
srsran_vec_div_ccc_simd(&num, &den, &ratio, 1);
alpha = atan2f(__imag__(ratio), __real__(ratio));

if (k_max > floor(N / 2)) {
k_max = -(N - k_max);
}
f_est = 1.0 * k_max / N + alpha * M_1_PI * 0.5f;

return -f_est;
}
31 changes: 26 additions & 5 deletions lib/src/phy/ch_estimation/chest_ul.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <strings.h>

#include "srsran/config.h"
#include "srsran/phy/ch_estimation/cedron_freq_estimator.h"
#include "srsran/phy/ch_estimation/chest_ul.h"
#include "srsran/phy/dft/dft_precoding.h"
#include "srsran/phy/utils/convolution.h"
Expand Down Expand Up @@ -98,6 +99,11 @@ int srsran_chest_ul_init(srsran_chest_ul_t* q, uint32_t max_prb)
ERROR("Error allocating memory for pregenerated signals");
goto clean_exit;
}

if (srsran_cedron_freq_est_init(&q->srsran_cedron_freq_est, max_prb)) {
ERROR("Error initializing cedron freq estimation algorithm.");
goto clean_exit;
}
}

ret = SRSRAN_SUCCESS;
Expand All @@ -117,6 +123,7 @@ void srsran_chest_ul_free(srsran_chest_ul_t* q)
free(q->tmp_noise);
}
srsran_interp_linear_vector_free(&q->srsran_interp_linvec);
srsran_cedron_freq_est_free(&q->srsran_cedron_freq_est);

if (q->pilot_estimates) {
free(q->pilot_estimates);
Expand Down Expand Up @@ -293,6 +300,7 @@ static void chest_ul_estimate(srsran_chest_ul_t* q,
uint32_t nrefs_sym,
uint32_t stride,
bool meas_ta_en,
bool use_cedron_alg,
bool write_estimates,
uint32_t n_prb[SRSRAN_NOF_SLOTS_PER_SF],
srsran_chest_ul_res_t* res)
Expand All @@ -310,7 +318,13 @@ static void chest_ul_estimate(srsran_chest_ul_t* q,
float ta_err = 0.0f;
if (meas_ta_en) {
for (int i = 0; i < nslots; i++) {
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[i * nrefs_sym], nrefs_sym) / nslots;
if (use_cedron_alg) {
ta_err +=
srsran_cedron_freq_estimate(&q->srsran_cedron_freq_est, &q->pilot_estimates[i * nrefs_sym], nrefs_sym) /
nslots;
} else {
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[i * nrefs_sym], nrefs_sym) / nslots;
}
}
}

Expand Down Expand Up @@ -412,7 +426,8 @@ int srsran_chest_ul_estimate_pusch(srsran_chest_ul_t* q,
nrefs_sf);

// Estimate
chest_ul_estimate(q, SRSRAN_NOF_SLOTS_PER_SF, nrefs_sym, 1, cfg->meas_ta_en, true, cfg->grant.n_prb, res);
chest_ul_estimate(
q, SRSRAN_NOF_SLOTS_PER_SF, nrefs_sym, 1, cfg->meas_ta_en, cfg->use_cedron_alg, true, cfg->grant.n_prb, res);

return 0;
}
Expand Down Expand Up @@ -515,8 +530,14 @@ int srsran_chest_ul_estimate_pucch(srsran_chest_ul_t* q,
float ta_err = 0.0f;
for (int ns = 0; ns < SRSRAN_NOF_SLOTS_PER_SF; ns++) {
for (int i = 0; i < n_rs; i++) {
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[(i + ns * n_rs) * SRSRAN_NRE], SRSRAN_NRE) /
(float)(SRSRAN_NOF_SLOTS_PER_SF * n_rs);
if (cfg->use_cedron_alg) {
ta_err += srsran_cedron_freq_estimate(
&q->srsran_cedron_freq_est, &q->pilot_estimates[(i + ns * n_rs) * SRSRAN_NRE], SRSRAN_NRE) /
(float)(SRSRAN_NOF_SLOTS_PER_SF * n_rs);
} else {
ta_err += srsran_vec_estimate_frequency(&q->pilot_estimates[(i + ns * n_rs) * SRSRAN_NRE], SRSRAN_NRE) /
(float)(SRSRAN_NOF_SLOTS_PER_SF * n_rs);
}
}
}

Expand Down Expand Up @@ -620,7 +641,7 @@ int srsran_chest_ul_estimate_srs(srsran_chest_ul_t* q,

// Estimate
uint32_t n_prb[2] = {};
chest_ul_estimate(q, 1, n_srs_re, 1, true, false, n_prb, res);
chest_ul_estimate(q, 1, n_srs_re, 1, true, false, false, n_prb, res);

return SRSRAN_SUCCESS;
}
1 change: 1 addition & 0 deletions lib/src/phy/fec/convolutional/viterbi37_avx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#define DEBUG

Expand Down
2 changes: 2 additions & 0 deletions lib/src/phy/fec/convolutional/viterbi37_avx2_16bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

//#define DEBUG

Expand Down
1 change: 1 addition & 0 deletions lib/src/phy/fec/convolutional/viterbi37_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#include "parity.h"
#include "viterbi37.h"
Expand Down
1 change: 1 addition & 0 deletions lib/src/phy/fec/convolutional/viterbi37_sse.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#define DEBUG

Expand Down
1 change: 1 addition & 0 deletions lib/src/phy/fec/polar/polar_interleaver.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "srsran/phy/utils/vector.h"
#include <memory.h>
#include <stddef.h>
#include <string.h>

// Table 5.3.1.1-1: Interleaving pattern
static const uint16_t polar_interleaver_pattern[SRSRAN_POLAR_INTERLEAVER_K_MAX_IL] = {
Expand Down
Loading

0 comments on commit 3eae95d

Please sign in to comment.