Enable FPGA acceleration for Galileo E6

This commit is contained in:
Marc Majoral
2026-09-25 21:26:20 +02:00
parent f543c9540d
commit 61d4447657
4 changed files with 110 additions and 6 deletions
@@ -7,7 +7,7 @@
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2025 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
@@ -21,9 +21,11 @@
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "Galileo_E5b.h"
#include "Galileo_E6.h"
#include "configuration_interface.h"
#include "galileo_e1_signal_replica.h"
#include "galileo_e5_signal_replica.h"
#include "galileo_e6_signal_replica.h"
#include "gnss_sdr_fft.h"
#include "gnss_sdr_flags.h"
#include "gps_l2c_signal_replica.h"
@@ -82,6 +84,8 @@ fpga_signal_info get_fpga_signal_info(signal_flag sig_flag)
return {GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS, 0, 13, ACQ_BUFF_1, GALILEO_E5A_NUMBER_OF_CODES};
case GAL_E5b:
return {GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_CODE_LENGTH_CHIPS, 0, 13, ACQ_BUFF_1, GALILEO_E5B_NUMBER_OF_CODES};
case GAL_E6:
return {GALILEO_E6_B_CODE_CHIP_RATE_CPS, GALILEO_E6_B_CODE_LENGTH_CHIPS, 0, 13, ACQ_BUFF_1, GALILEO_E6_NUMBER_OF_CODES};
default:
break;
}
@@ -172,6 +176,10 @@ void generate_code(signal_flag sig_flag,
}
galileo_e5_b_code_gen_complex_sampled(code, prn, signal, acq_parameters.fs_in, 0);
}
case GAL_E6:
{
galileo_e6_b_code_gen_complex_sampled(code, prn, acq_parameters.fs_in, 0);
}
break;
default:
break;
@@ -7,7 +7,7 @@
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2025 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
@@ -20,10 +20,12 @@
#include "GPS_L5.h"
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "Galileo_E6.h"
#include "configuration_interface.h"
#include "display.h"
#include "galileo_e1_signal_replica.h"
#include "galileo_e5_signal_replica.h"
#include "galileo_e6_signal_replica.h"
#include "gps_l2c_signal_replica.h"
#include "gps_l5_signal_replica.h"
#include "gps_sdr_signal_replica.h"
@@ -84,10 +86,11 @@ tracking_fpga_signal_info get_tracking_fpga_signal_info(signal_flag sig_flag)
return {'E', {'1', 'B', '\0'}, "1B", GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_B_CODE_LENGTH_CHIPS, GALILEO_E1_NUMBER_OF_CODES, 2};
case GAL_E5a:
return {'E', {'5', 'X', '\0'}, "5X", GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS, GALILEO_E5A_NUMBER_OF_CODES, 1};
case GAL_E6:
return {'E', {'E', '6', '\0'}, "E6", GALILEO_E6_B_CODE_CHIP_RATE_CPS, GALILEO_E6_B_CODE_LENGTH_CHIPS, GALILEO_E6_NUMBER_OF_CODES, 1};
default:
break;
}
return {};
}
@@ -112,6 +115,7 @@ const std::map<std::string, std::string> DllPllTrackingAdapterFpga::signal_to_de
{"L5", "multicorrelator_resampler_3_1_AXI"},
{"1B", "multicorrelator_resampler_5_1_AXI"},
{"5X", "multicorrelator_resampler_3_1_AXI"},
{"E6", "multicorrelator_resampler_3_1_AXI"},
};
const std::map<std::string, std::string> DllPllTrackingAdapterFpga::signal_to_alternative_device_ = {
@@ -265,6 +269,24 @@ void DllPllTrackingAdapterFpga::configure_signal_parameters(const ConfigurationI
}
warn_narrow_bw("Galileo E5a", trk_params_);
break;
case GAL_E6:
if (trk_params_.extend_correlation_symbols < 1)
{
trk_params_.extend_correlation_symbols = 1;
std::cout << TEXT_RED
<< "WARNING: Galileo E6. extend_correlation_symbols must be >= 1. "
<< "Set to 1 symbol (1 ms)." << TEXT_RESET << '\n';
}
else if (!trk_params_.track_pilot && trk_params_.extend_correlation_symbols > 1)
{
trk_params_.extend_correlation_symbols = 1;
std::cout << TEXT_RED
<< "WARNING: Galileo E6. Extended coherent integration is only supported "
<< "when tracking the pilot component. Set to 1 ms (1 symbol)."
<< TEXT_RESET << '\n';
}
warn_narrow_bw("Galileo E6", trk_params_);
break;
default:
break;
}
@@ -321,7 +343,7 @@ void DllPllTrackingAdapterFpga::generate_prn_codes()
volk_gnsssdr_malloc(code_samples * sig_info.num_prns * sizeof(int32_t),
volk_gnsssdr_get_alignment()));
if (trk_params_.track_pilot && (sig_flag_ == GAL_1B || sig_flag_ == GAL_E5a || sig_flag_ == GPS_L5))
if (trk_params_.track_pilot && (sig_flag_ == GAL_1B || sig_flag_ == GAL_E5a || sig_flag_ == GPS_L5 || sig_flag_ == GAL_E6))
{
data_codes_ptr_ = static_cast<int32_t*>(
volk_gnsssdr_malloc(code_samples * sig_info.num_prns * sizeof(int32_t),
@@ -455,6 +477,37 @@ void DllPllTrackingAdapterFpga::generate_prn_codes()
}
}
break;
case GAL_E6:
{
volk_gnsssdr::vector<float> ca_codes_f(code_length_chips, 0.0F);
volk_gnsssdr::vector<float> data_codes_f(code_length_chips, 0.0F);
for (uint32_t prn = 1; prn <= sig_info.num_prns; prn++)
{
if (trk_params_.track_pilot)
{
galileo_e6_c_code_gen_float_primary(ca_codes_f, prn);
galileo_e6_b_code_gen_float_primary(data_codes_f, prn);
}
else
{
galileo_e6_b_code_gen_float_primary(ca_codes_f, prn);
}
for (uint32_t s = 0; s < code_length_chips; s++)
{
int32_t pilot = (ca_codes_f[s] < 0) ? 0 : 1;
pilot |= LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY;
prn_codes_ptr_[code_length_chips * (prn - 1) + s] = pilot;
if (trk_params_.track_pilot)
{
int32_t data = (data_codes_f[s] < 0) ? 0 : 1;
data |= LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY |
LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT;
data_codes_ptr_[code_length_chips * (prn - 1) + s] = data;
}
}
}
}
default:
break;
}
@@ -1,7 +1,7 @@
/*!
* \file dll_pll_veml_tracking_fpga.cc
* \brief Implementation of a code DLL + carrier PLL tracking block using an FPGA
* \author Marc Majoral, 2019. marc.majoral(at)cttc.es
* \author Marc Majoral, 2019-2026. marc.majoral(at)cttc.es
* \author Javier Arribas, 2019. jarribas(at)cttc.es
*
* Code DLL + carrier PLL according to the algorithms described in:
@@ -14,7 +14,7 @@
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
@@ -26,8 +26,10 @@
#include "GPS_L5.h"
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "Galileo_E6.h"
#include "MATH_CONSTANTS.h"
#include "fpga_multicorrelator.h"
#include "galileo_e6_signal_replica.h"
#include "gnss_satellite.h"
#include "gnss_sdr_create_directory.h"
#include "gnss_sdr_filesystem.h"
@@ -169,6 +171,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &
map_signal_pretty_name["2G"] = "L2 C/A";
map_signal_pretty_name["5X"] = "E5a";
map_signal_pretty_name["L5"] = "L5";
map_signal_pretty_name["E6"] = "E6";
d_signal_pretty_name = map_signal_pretty_name[d_signal_type];
@@ -325,6 +328,29 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &
d_signal_pretty_name = d_signal_pretty_name + "I";
}
}
else if (d_signal_type == "E6")
{
d_signal_carrier_freq = GALILEO_E6_FREQ_HZ;
d_code_period = GALILEO_E6_CODE_PERIOD_S;
d_code_chip_rate = GALILEO_E6_B_CODE_CHIP_RATE_CPS;
// Galileo E6 has 1 trk symbol (4 ms) per tlm bit, no symbol integration required
d_symbols_per_bit = 1;
d_correlation_length_ms = GALILEO_E6_CODE_PERIOD_MS;
d_trk_parameters.spc = d_trk_parameters.early_late_space_chips;
d_trk_parameters.slope = 1.0;
d_trk_parameters.y_intercept = 1.0;
if (d_trk_parameters.track_pilot)
{
d_secondary = true;
d_secondary_code_length = static_cast<uint32_t>(GALILEO_E6_C_SECONDARY_CODE_LENGTH_CHIPS);
d_signal_pretty_name = d_signal_pretty_name + "C";
}
else
{
d_secondary = false;
d_signal_pretty_name = d_signal_pretty_name + "B";
}
}
else
{
LOG(WARNING) << "Invalid Signal argument when instantiating tracking blocks";
@@ -1399,6 +1425,15 @@ void dll_pll_veml_tracking_fpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
}
}
}
else if (d_systemName == "Galileo" && d_signal_type == "E6")
{
if (d_trk_parameters.track_pilot)
{
d_Prompt_Data[0] = gr_complex(0.0, 0.0);
d_secondary_code_string = galileo_e6_c_secondary_code(d_acquisition_gnss_synchro->PRN);
}
}
std::fill_n(d_correlator_outs.begin(), d_n_correlator_taps, gr_complex(0.0, 0.0));
+8
View File
@@ -560,6 +560,10 @@ std::unique_ptr<AcquisitionInterface> get_acq_block(
{
return std::make_unique<PcpsAcquisitionAdapterFpga>(configuration, role, implementation, in_streams, out_streams, GAL_E5b);
}
else if (implementation == "Galileo_E6_PCPS_Acquisition_FPGA")
{
return std::make_unique<PcpsAcquisitionAdapterFpga>(configuration, role, implementation, in_streams, out_streams, GAL_E6);
}
#endif
return nullptr;
@@ -680,6 +684,10 @@ std::unique_ptr<TrackingInterface> get_trk_block(
{
return std::make_unique<DllPllTrackingAdapterFpga>(configuration, role, implementation, in_streams, out_streams, GAL_E5a);
}
else if (implementation == "Galileo_E6_DLL_PLL_Tracking_FPGA")
{
return std::make_unique<DllPllTrackingAdapterFpga>(configuration, role, implementation, in_streams, out_streams, GAL_E6);
}
#endif
return nullptr;