From 5c0826b11e1b864d0f4be4624d83554a6e2ff9fb Mon Sep 17 00:00:00 2001 From: Marc Majoral Date: Wed, 13 Sep 2023 17:19:10 +0200 Subject: [PATCH] Optimize the use of the FPGA dynamic bit selection blocks. Reorder AD9361 FPGA signal source private members by size. use ssize_t write() return value. --- .../adapters/ad9361_fpga_signal_source.cc | 55 +++---- .../adapters/ad9361_fpga_signal_source.h | 22 +-- .../libs/fpga_dynamic_bit_selection.cc | 143 +++++++----------- .../libs/fpga_dynamic_bit_selection.h | 18 +-- src/core/libs/gnss_sdr_fpga_sample_counter.cc | 6 +- 5 files changed, 99 insertions(+), 145 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 065838450..0caa240f0 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -59,26 +59,26 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con filename0_(configuration->property(role + ".filename", empty_string)), rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), + scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), + phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), + tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), freq0_(configuration->property(role + ".freq", 0)), freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), samples_to_skip_(0), samples_(configuration->property(role + ".samples", static_cast(0))), + freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), + freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), + tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), num_freq_bands_(2), dma_buff_offset_pos_(0), - scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), - phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), - tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), - freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), - freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), - tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), - item_size_(sizeof(int8_t)), in_stream_(in_stream), out_stream_(out_stream), switch_position_(configuration->property(role + ".switch_position", 0)), + item_size_(sizeof(int8_t)), enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)), filter_auto_(configuration->property(role + ".filter_auto", false)), quadrature_(configuration->property(role + ".quadrature", true)), @@ -93,11 +93,17 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)), repeat_(configuration->property(role + ".repeat", false)) { - const int l1_band = configuration->property("Channels_1C.count", 0) + - configuration->property("Channels_1B.count", 0); - const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0); const size_t header_size = configuration->property(role + ".header_size", 0); + const int num_ch_rx1 = configuration->property("Channels_1C.count", 0) + + configuration->property("Channels_1B.count", 0); + const int num_ch_rx2 = (configuration->property("Channels_L2.count", 0) > 0) ? configuration->property("Channels_L2.count", 0) : configuration->property("Channels_L5.count", 0) + configuration->property("Channels_5X.count", 0); + + // number of frequency bands + if (num_ch_rx2 == 0) + { + num_freq_bands_ = 1; + } if (freq0_ == 0) { @@ -135,8 +141,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. if (filename1_.empty()) { - num_freq_bands_ = 1; - if (l1_band != 0) + if (num_ch_rx1 != 0) { dma_buff_offset_pos_ = 2; } @@ -160,7 +165,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0) { std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << '\n'; - item_size_ = 0; return; } @@ -196,7 +200,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con else { std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; - item_size_ = 0; return; } std::streamsize ss = std::cout.precision(); @@ -224,7 +227,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con else { std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; - item_size_ = 0; return; } std::streamsize ss = std::cout.precision(); @@ -372,7 +374,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con catch (const std::runtime_error &e) { std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; - item_size_ = 0; return; } // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION @@ -407,7 +408,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con catch (const std::runtime_error &e) { std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; - item_size_ = 0; return; } } @@ -424,7 +424,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0) { std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << '\n'; - item_size_ = 0; return; } @@ -435,25 +434,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con // dynamic bits selection if (enable_dynamic_bit_selection_) { - std::string device_io_name_dyn_bit_sel_0; - std::string device_io_name_dyn_bit_sel_1; - - // find the uio device file corresponding to the dynamic bit selector 0 module. - if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_0, dyn_bit_sel_device_name, 0) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; - item_size_ = 0; - return; - } - - // find the uio device file corresponding to the dynamic bit selector 1 module. - if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_1, dyn_bit_sel_device_name, 1) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; - item_size_ = 0; - return; - } - dynamic_bit_selection_fpga = std::make_shared(device_io_name_dyn_bit_sel_0, device_io_name_dyn_bit_sel_1); + dynamic_bit_selection_fpga = std::make_shared(num_freq_bands_); thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); } diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index f16f6f274..a78b1aa00 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -118,7 +118,6 @@ private: Concurrent_Queue *queue_; - // Front-end settings std::string gain_mode_rx1_; std::string gain_mode_rx2_; std::string rf_port_select_; @@ -130,30 +129,31 @@ private: double rf_gain_rx1_; double rf_gain_rx2_; + double scale_dds_dbfs_; + double phase_dds_deg_; + double tx_attenuation_db_; + uint64_t freq0_; // frequency of local oscillator for ADRV9361-A 0 uint64_t freq1_; // frequency of local oscillator for ADRV9361-B (if present) uint64_t sample_rate_; uint64_t bandwidth_; uint64_t samples_to_skip_; int64_t samples_; + uint64_t freq_dds_tx_hz_; + uint64_t freq_rf_tx_hz_; + uint64_t tx_bandwidth_; + float Fpass_; float Fstop_; uint32_t num_freq_bands_; uint32_t dma_buff_offset_pos_; - - // DDS configuration for LO generation for external mixer - double scale_dds_dbfs_; - double phase_dds_deg_; - double tx_attenuation_db_; - uint64_t freq_dds_tx_hz_; - uint64_t freq_rf_tx_hz_; - uint64_t tx_bandwidth_; - size_t item_size_; uint32_t in_stream_; uint32_t out_stream_; int32_t switch_position_; - bool enable_dds_lo_; + size_t item_size_; + + bool enable_dds_lo_; bool filter_auto_; bool quadrature_; bool rf_dc_; diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc index 0e7a5afca..c897e40f5 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc @@ -2,7 +2,7 @@ * \file fpga_dynamic_bit_selection.cc * \brief Dynamic Bit Selection in the received signal. * \authors
    - *
  • Marc Majoral, 2020. mmajoral(at)cttc.es + *
  • Marc Majoral, 2023. mmajoral(at)cttc.es *
* * Class that controls the Dynamic Bit Selection in the FPGA. @@ -13,58 +13,52 @@ * 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-2023 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #include "fpga_dynamic_bit_selection.h" +#include "uio_fpga.h" #include #include // for open, O_RDWR, O_SYNC #include // for cout #include // for mmap -Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(const std::string &device_name1, const std::string &device_name2) +Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(uint32_t num_freq_bands) + : d_num_freq_bands(num_freq_bands) { - // dynamic bits selection corresponding to frequency band 1 - if ((d_device_descriptor1 = open(device_name1.c_str(), O_RDWR | O_SYNC)) == -1) + d_map_base = std::vector(d_num_freq_bands); + d_device_descriptors = std::vector(d_num_freq_bands); + d_shift_out_bits = std::vector(d_num_freq_bands); + for (uint32_t k = 0; k < d_num_freq_bands; k++) { - LOG(WARNING) << "Cannot open deviceio" << device_name1; + // find the uio device file corresponding to the dynamic bit selector 0 module. + std::string device_name; + if (find_uio_dev_file_name(device_name, dyn_bit_sel_device_name, 0) < 0) + { + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; + return; + } + // dynamic bits selection corresponding to frequency band 1 + if ((d_device_descriptors[k] = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_name; + } + d_map_base[k] = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptors[k], 0)); + + if (d_map_base[k] == reinterpret_cast(-1)) + { + LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory"; + std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; + } + + // init bit selection corresopnding to frequency band 1 + d_shift_out_bits[k] = shift_out_bits_default; + d_map_base[k][0] = d_shift_out_bits[k]; } - d_map_base1 = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor1, 0)); - - if (d_map_base1 == reinterpret_cast(-1)) - { - LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory"; - std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; - } - - // dynamic bits selection corresponding to frequency band 2 - if ((d_device_descriptor2 = open(device_name2.c_str(), O_RDWR | O_SYNC)) == -1) - { - LOG(WARNING) << "Cannot open deviceio" << device_name2; - } - d_map_base2 = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor2, 0)); - - if (d_map_base2 == reinterpret_cast(-1)) - { - LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 2 into tracking memory"; - std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 2.\n"; - } - - // initialize default bit selection - shift_out_bits_band1 = shift_out_bits_default; - shift_out_bits_band2 = shift_out_bits_default; - - // init bit selection corresopnding to frequency band 1 - d_map_base1[0] = shift_out_bits_band1; - - // init bit selection corresponding to frequency band 2 - d_map_base2[0] = shift_out_bits_band2; - DLOG(INFO) << "Dynamic bit selection FPGA class created"; } @@ -77,65 +71,42 @@ Fpga_dynamic_bit_selection::~Fpga_dynamic_bit_selection() void Fpga_dynamic_bit_selection::bit_selection() { - // estimated signal power corresponding to frequency band 1 - uint32_t rx_signal_power1 = d_map_base1[1]; - // estimated signal power corresponding to frequency band 2 - uint32_t rx_signal_power2 = d_map_base2[1]; - - // dynamic bit selection corresponding to frequency band 1 - if (rx_signal_power1 > Power_Threshold_High) + for (uint32_t k = 0; k < d_num_freq_bands; k++) { - if (shift_out_bits_band1 < shift_out_bit_max) - { - shift_out_bits_band1 = shift_out_bits_band1 + 1; - } - } - else if (rx_signal_power1 < Power_Threshold_Low) - { - if (shift_out_bits_band1 > shift_out_bits_min) - { - shift_out_bits_band1 = shift_out_bits_band1 - 1; - } - } + // estimated signal power + uint32_t rx_signal_power = d_map_base[k][1]; - // dynamic bit selection corresponding to frequency band 2 - if (rx_signal_power2 > Power_Threshold_High) - { - if (shift_out_bits_band2 < shift_out_bit_max) + // dynamic bit selection + if (rx_signal_power > Power_Threshold_High) { - shift_out_bits_band2 = shift_out_bits_band2 + 1; + if (d_shift_out_bits[k] < shift_out_bit_max) + { + d_shift_out_bits[k] = d_shift_out_bits[k] + 1; + } } - } - else if (rx_signal_power2 < Power_Threshold_Low) - { - if (shift_out_bits_band2 > shift_out_bits_min) + else if (rx_signal_power < Power_Threshold_Low) { - shift_out_bits_band2 = shift_out_bits_band2 - 1; + if (d_shift_out_bits[k] > shift_out_bits_min) + { + d_shift_out_bits[k] = d_shift_out_bits[k] - 1; + } } + + // update bit selection corresopnding to frequency band 1 + d_map_base[k][0] = d_shift_out_bits[k]; } - - // update bit selection corresopnding to frequency band 1 - d_map_base1[0] = shift_out_bits_band1; - - // udpate bit selection corresponding to frequency band 2 - d_map_base2[0] = shift_out_bits_band2; } void Fpga_dynamic_bit_selection::close_devices() { - auto *aux = const_cast(d_map_base1); - if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) + for (uint32_t k = 0; k < d_num_freq_bands; k++) { - std::cout << "Failed to unmap memory uio\n"; + auto *aux = const_cast(d_map_base[k]); + if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) + { + std::cout << "Failed to unmap memory uio\n"; + } + close(d_device_descriptors[k]); } - - aux = const_cast(d_map_base2); - if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) - { - std::cout << "Failed to unmap memory uio\n"; - } - - close(d_device_descriptor1); - close(d_device_descriptor2); } diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h index 500bb182e..f5454e299 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h @@ -25,6 +25,7 @@ #include #include #include +#include /** \addtogroup Signal_Source * \{ */ @@ -42,7 +43,7 @@ public: /*! * \brief Constructor */ - explicit Fpga_dynamic_bit_selection(const std::string& device_name1, const std::string& device_name2); + explicit Fpga_dynamic_bit_selection(uint32_t num_freq_bands); /*! * \brief Destructor @@ -52,12 +53,12 @@ public: /*! * \brief This function configures the switch in th eFPGA */ - // void set_switch_position(int32_t switch_position); void bit_selection(void); private: + const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name + const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name static const size_t FPGA_PAGE_SIZE = 0x1000; - static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC static const uint32_t Num_bits_FPGA = 4; // Number of bits after the bit selection static const uint32_t shift_out_bits_default = Num_bits_ADC - Num_bits_FPGA; // take the most significant bits by default @@ -70,14 +71,11 @@ private: void close_devices(void); - uint32_t shift_out_bits_band1; // number of bits to shift for frequency band 1 - uint32_t shift_out_bits_band2; // number of bits to shift for frequency band 2 + std::vector d_map_base; + std::vector d_device_descriptors; + std::vector d_shift_out_bits; - volatile unsigned* d_map_base1; // driver memory map corresponding to frequency band 1 - int d_device_descriptor1; // driver descriptor corresponding to frequency band 1 - - volatile unsigned* d_map_base2; // driver memory map corresponding to frequency band 2 - int d_device_descriptor2; // driver descriptor corresponding to frequency band 2 + uint32_t d_num_freq_bands; // number of frequency bands }; diff --git a/src/core/libs/gnss_sdr_fpga_sample_counter.cc b/src/core/libs/gnss_sdr_fpga_sample_counter.cc index a54fd6270..6aa5c44a8 100644 --- a/src/core/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/core/libs/gnss_sdr_fpga_sample_counter.cc @@ -279,7 +279,11 @@ void gnss_sdr_fpga_sample_counter::wait_for_interrupt() const // enable interrupts int32_t reenable = 1; - write(fd, reinterpret_cast(&reenable), sizeof(int32_t)); + const ssize_t nbytes = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast(&reenable), sizeof(int32_t))); + if (nbytes != sizeof(int32_t)) + { + std::cerr << "Error re-enabling FPGA sample counter interrupt.\n"; + } // wait for interrupt nb = read(fd, &irq_count, sizeof(irq_count));