aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2018-01-22 09:47:21 -0800
committerMartin Braun <martin.braun@ettus.com>2018-02-19 14:51:47 -0800
commiteff796f64b1e05036b7eca2185f53528a0de870b (patch)
treea470a6d1f3f3d2bb8a422b8b7f3815f2924c766c
parent1adae2b432d1b66d7b9133a67fedce8af0b6b560 (diff)
downloaduhd-eff796f64b1e05036b7eca2185f53528a0de870b.tar.gz
uhd-eff796f64b1e05036b7eca2185f53528a0de870b.tar.bz2
uhd-eff796f64b1e05036b7eca2185f53528a0de870b.zip
rfnoc: Factored out FPGA compat check
- Applied changes to DUC and DDC blocks - Fixed minor formatting
-rw-r--r--host/lib/include/uhdlib/utils/compat_check.hpp30
-rw-r--r--host/lib/rfnoc/ddc_block_ctrl_impl.cpp88
-rw-r--r--host/lib/rfnoc/duc_block_ctrl_impl.cpp90
-rw-r--r--host/lib/utils/CMakeLists.txt1
-rw-r--r--host/lib/utils/compat_check.cpp114
5 files changed, 234 insertions, 89 deletions
diff --git a/host/lib/include/uhdlib/utils/compat_check.hpp b/host/lib/include/uhdlib/utils/compat_check.hpp
new file mode 100644
index 000000000..acdf97340
--- /dev/null
+++ b/host/lib/include/uhdlib/utils/compat_check.hpp
@@ -0,0 +1,30 @@
+//
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0
+//
+
+#ifndef INCLUDED_UHDLIB_UTILS_COMPATCHECK_HPP
+#define INCLUDED_UHDLIB_UTILS_COMPATCHECK_HPP
+
+#include <cstddef>
+#include <string>
+
+namespace uhd {
+
+ /*! Checks for FPGA compatibility, and throws an exception on mismatch.
+ *
+ * \throws uhd::runtime_error on mismatch.
+ */
+ void assert_fpga_compat(
+ const size_t uhd_major,
+ const size_t uhd_minor,
+ const uint64_t fpga_compat,
+ const std::string& fpga_component,
+ const std::string& log_component,
+ const bool fail_on_minor_behind=false
+ );
+
+} /* namespace uhd */
+
+#endif /* INCLUDED_UHDLIB_UTILS_COMPATCHECK_HPP */
diff --git a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp
index 62a5ce896..9c7764045 100644
--- a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp
+++ b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp
@@ -9,6 +9,8 @@
#include <uhd/utils/log.hpp>
#include <uhd/convert.hpp>
#include <uhd/types/ranges.hpp>
+#include <uhdlib/utils/narrow.hpp>
+#include <uhdlib/utils/compat_check.hpp>
#include <boost/math/special_functions/round.hpp>
#include <cmath>
@@ -24,10 +26,23 @@ class ddc_block_ctrl_impl : public ddc_block_ctrl
public:
UHD_RFNOC_BLOCK_CONSTRUCTOR(ddc_block_ctrl)
+ , _fpga_compat(user_reg_read64(RB_REG_COMPAT_NUM))
+ , _num_halfbands(uhd::narrow_cast<size_t>(
+ user_reg_read64(RB_REG_NUM_HALFBANDS)))
+ , _cic_max_decim(uhd::narrow_cast<size_t>(
+ user_reg_read64(RB_REG_CIC_MAX_DECIM)))
{
- check_compat_num();
- _num_halfbands = (size_t) user_reg_read64(RB_REG_NUM_HALFBANDS);
- _cic_max_decim = (size_t) user_reg_read64(RB_REG_CIC_MAX_DECIM);
+ UHD_LOG_DEBUG(unique_id(),
+ "Loading DDC with " << get_num_halfbands() << " halfbands and "
+ "max CIC decimation " << get_cic_max_decim()
+ );
+ uhd::assert_fpga_compat(
+ MAJOR_COMP, MINOR_COMP,
+ _fpga_compat,
+ "DDC", "DDC",
+ false /* Let it slide if minors mismatch */
+ );
+
// Argument/prop tree hooks
for (size_t chan = 0; chan < get_input_ports().size(); chan++) {
double default_freq = get_arg<double>("freq", chan);
@@ -186,14 +201,15 @@ public:
}
private:
+ static constexpr size_t MAJOR_COMP = 1;
+ static constexpr size_t MINOR_COMP = 0;
+ static constexpr size_t RB_REG_COMPAT_NUM = 0;
+ static constexpr size_t RB_REG_NUM_HALFBANDS = 1;
+ static constexpr size_t RB_REG_CIC_MAX_DECIM = 2;
- size_t _num_halfbands;
- size_t _cic_max_decim;
- static const size_t MAJOR_COMP = 1;
- static const size_t MINOR_COMP = 0;
- static const size_t RB_REG_COMPAT_NUM = 0;
- static const size_t RB_REG_NUM_HALFBANDS = 1;
- static const size_t RB_REG_CIC_MAX_DECIM = 2;
+ const uint64_t _fpga_compat;
+ const size_t _num_halfbands;
+ const size_t _cic_max_decim;
//! Set the CORDIC frequency shift the signal to \p requested_freq
double set_freq(const double requested_freq, const size_t chan)
@@ -224,7 +240,7 @@ private:
for (int hb = _num_halfbands; hb >= 0; hb--) {
const size_t decim_offset = _cic_max_decim<<(hb-1);
for(size_t decim = _cic_max_decim; decim > 0; decim--) {
- const size_t hb_cic_decim = decim*(1<<hb);
+ const size_t hb_cic_decim = decim*(1<<hb);
if(hb == 0 || hb_cic_decim > decim_offset) {
range.push_back(uhd::range_t(input_rate/hb_cic_decim));
}
@@ -315,39 +331,23 @@ private:
sr_write("SCALE_IQ", actual_scalar, chan);
}
- //Get cached value of _num_halfbands
- size_t get_num_halfbands() const
- {
- return _num_halfbands;
- }
-
- //Get cached value of _cic_max_decim readback
- size_t get_cic_max_decim() const
- {
- return _cic_max_decim;
- }
-
- //Check compatibility num, if not current, throw error.
- //MAJOR COMPATIBILITY, top 32 bits = 0x1
- //MINOR COMPATIBILITY, lower 32 bits = 0x0
- void check_compat_num()
- {
- uint64_t compat_num = user_reg_read64(RB_REG_COMPAT_NUM);
- uint32_t compat_num_major = compat_num>>32;
- uint32_t compat_num_minor = compat_num&0xFFFFFFFF;
- if (compat_num_major > MAJOR_COMP) {
- throw uhd::runtime_error(str(boost::format(
- "DDC RFNoC block is too new for this software. Please upgrade to a driver that supports hardware revision %d.")
- % compat_num_major));
- } else if (compat_num_major < MAJOR_COMP) {
- throw uhd::runtime_error(str(boost::format(
- "DDC software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.")
- % compat_num_major));
- }
- if (compat_num_minor != MINOR_COMP) {
- UHD_LOGGER_WARNING("DDC") << "DDC hardware compatability does not match software, this may have adverse affects on the block's behavior.";
- }
- }
+ //! Get cached value of FPGA compat number
+ uint64_t get_fpga_compat() const
+ {
+ return _fpga_compat;
+ }
+
+ //! Get cached value of _num_halfbands
+ size_t get_num_halfbands() const
+ {
+ return _num_halfbands;
+ }
+
+ //! Get cached value of _cic_max_decim readback
+ size_t get_cic_max_decim() const
+ {
+ return _cic_max_decim;
+ }
};
UHD_RFNOC_BLOCK_REGISTER(ddc_block_ctrl, "DDC");
diff --git a/host/lib/rfnoc/duc_block_ctrl_impl.cpp b/host/lib/rfnoc/duc_block_ctrl_impl.cpp
index 3a779566b..0e1521d9f 100644
--- a/host/lib/rfnoc/duc_block_ctrl_impl.cpp
+++ b/host/lib/rfnoc/duc_block_ctrl_impl.cpp
@@ -9,6 +9,8 @@
#include <uhd/utils/log.hpp>
#include <uhd/convert.hpp>
#include <uhd/types/ranges.hpp>
+#include <uhdlib/utils/narrow.hpp>
+#include <uhdlib/utils/compat_check.hpp>
#include <boost/math/special_functions/round.hpp>
#include <cmath>
@@ -35,10 +37,23 @@ class duc_block_ctrl_impl : public duc_block_ctrl
public:
UHD_RFNOC_BLOCK_CONSTRUCTOR(duc_block_ctrl)
+ , _fpga_compat(user_reg_read64(RB_REG_COMPAT_NUM))
+ , _num_halfbands(uhd::narrow_cast<size_t>(
+ user_reg_read64(RB_REG_NUM_HALFBANDS)))
+ , _cic_max_interp(uhd::narrow_cast<size_t>(
+ user_reg_read64(RB_REG_CIC_MAX_INTERP)))
{
- check_compat_num();
- _num_halfbands = (size_t) user_reg_read64(RB_REG_NUM_HALFBANDS);
- _cic_max_interp = (size_t) user_reg_read64(RB_REG_CIC_MAX_INTERP);
+ UHD_LOG_DEBUG(unique_id(),
+ "Loading DUC with " << get_num_halfbands() << " halfbands and "
+ "max CIC interpolation " << get_cic_max_interp()
+ );
+ uhd::assert_fpga_compat(
+ MAJOR_COMP, MINOR_COMP,
+ _fpga_compat,
+ "DUC", "DUC",
+ false /* Let it slide if minors mismatch */
+ );
+
// Argument/prop tree hooks
for (size_t chan = 0; chan < get_input_ports().size(); chan++) {
double default_freq = get_arg<double>("freq", chan);
@@ -149,13 +164,15 @@ public:
private:
- size_t _num_halfbands;
- size_t _cic_max_interp;
- static const size_t MAJOR_COMP = 1;
- static const size_t MINOR_COMP = 0;
- static const size_t RB_REG_COMPAT_NUM = 0;
- static const size_t RB_REG_NUM_HALFBANDS = 1;
- static const size_t RB_REG_CIC_MAX_INTERP = 2;
+ static constexpr size_t MAJOR_COMP = 1;
+ static constexpr size_t MINOR_COMP = 0;
+ static constexpr size_t RB_REG_COMPAT_NUM = 0;
+ static constexpr size_t RB_REG_NUM_HALFBANDS = 1;
+ static constexpr size_t RB_REG_CIC_MAX_INTERP = 2;
+
+ const uint64_t _fpga_compat;
+ const size_t _num_halfbands;
+ const size_t _cic_max_interp;
//! Set the CORDIC frequency shift the signal to \p requested_freq
double set_freq(const double requested_freq, const size_t chan)
@@ -187,7 +204,7 @@ private:
for (int hb = _num_halfbands; hb >= 0; hb--) {
const size_t interp_offset = _cic_max_interp<<(hb-1);
for(size_t interp = _cic_max_interp; interp > 0; interp--) {
- const size_t hb_cic_interp = interp*(1<<hb);
+ const size_t hb_cic_interp = interp*(1<<hb);
if(hb == 0 || hb_cic_interp > interp_offset) {
range.push_back(uhd::range_t(output_rate/hb_cic_interp));
}
@@ -263,40 +280,23 @@ private:
sr_write("SCALE_IQ", actual_scalar, chan);
}
- //Get cached value of _num_halfbands
- size_t get_num_halfbands() const
- {
- return (size_t) _num_halfbands;
- }
-
- //Get cached value of _cic_max_decim readback
- size_t get_cic_max_decim() const
- {
- return (size_t) _cic_max_interp;
- }
-
- //Check compatibility num, if not current, throw error.
- //MAJOR COMPATIBILITY, top 32 bits = 0x1
- //MINOR COMPATIBILITY, lower 32 bits = 0x0
- void check_compat_num()
- {
- uint64_t compat_num = user_reg_read64(RB_REG_COMPAT_NUM);
- uint32_t compat_num_major = compat_num>>32;
- uint32_t compat_num_minor = compat_num&0xFFFFFFFF;
- if ( compat_num_major > MAJOR_COMP) {
- throw uhd::runtime_error(str(boost::format(
- "DUC RFNoC block is too new for this software. Please upgrade to a driver that supports hardware revision %d.")
- % compat_num_major));
- } else if ( compat_num_major < MAJOR_COMP) {
- throw uhd::runtime_error(str(boost::format(
- "DUC software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.")
- % compat_num_major));
- }
- if (compat_num_minor != MINOR_COMP) {
- UHD_LOGGER_WARNING("DDC") << "DDC hardware compatability does not match software, this may have adverse affects on the block's behavior.";
- }
- }
+ //! Get cached value of FPGA compat number
+ uint64_t get_fpga_compat() const
+ {
+ return _fpga_compat;
+ }
+
+ //Get cached value of _num_halfbands
+ size_t get_num_halfbands() const
+ {
+ return _num_halfbands;
+ }
+
+ //Get cached value of _cic_max_decim readback
+ size_t get_cic_max_interp() const
+ {
+ return _cic_max_interp;
+ }
};
UHD_RFNOC_BLOCK_REGISTER(duc_block_ctrl, "DUC");
-
diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt
index afaf99274..c7de9fbf8 100644
--- a/host/lib/utils/CMakeLists.txt
+++ b/host/lib/utils/CMakeLists.txt
@@ -160,6 +160,7 @@ SET_SOURCE_FILES_PROPERTIES(
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/csv.cpp
${CMAKE_CURRENT_SOURCE_DIR}/config_parser.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/compat_check.cpp
${CMAKE_CURRENT_SOURCE_DIR}/eeprom_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ihex.cpp
diff --git a/host/lib/utils/compat_check.cpp b/host/lib/utils/compat_check.cpp
new file mode 100644
index 000000000..aebf6e6bf
--- /dev/null
+++ b/host/lib/utils/compat_check.cpp
@@ -0,0 +1,114 @@
+//
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0
+//
+
+#include <uhd/exception.hpp>
+#include <uhd/utils/log.hpp>
+#include <uhdlib/utils/compat_check.hpp>
+#include <boost/format.hpp>
+
+void uhd::assert_fpga_compat(
+ const size_t uhd_major,
+ const size_t uhd_minor,
+ const uint64_t fpga_compat,
+ const std::string& fpga_component,
+ const std::string& log_component,
+ const bool fail_on_minor_behind
+) {
+ const size_t fpga_major = fpga_compat >> 32;
+ const size_t fpga_minor = fpga_compat & 0xFFFFFFFF;
+
+ if (!log_component.empty()) {
+ UHD_LOGGER_DEBUG(log_component)
+ << "Checking compat number for FPGA component `" << fpga_component
+ << "': Expecting " << uhd_major << "." << uhd_minor << ", actual: "
+ << fpga_major << "." << fpga_minor << "."
+ ;
+ }
+
+ if (uhd_major > fpga_major) {
+ if (!log_component.empty()) {
+ UHD_LOGGER_ERROR(log_component)
+ << "Major compat number mismatch for " << fpga_component << ":"
+ " Expecting " << uhd_major << ", got " << fpga_major << "."
+ ;
+ }
+ throw uhd::runtime_error(str(
+ boost::format("FPGA component `%s' is revision %d and UHD supports"
+ " revision %d. Please either upgrade the FPGA"
+ " image (recommended) or downgrade UHD.")
+ % fpga_component
+ % fpga_major
+ % uhd_major
+ ));
+ }
+ if (uhd_major < fpga_major) {
+ if (!log_component.empty()) {
+ UHD_LOGGER_ERROR(log_component)
+ << "Major compat number mismatch for " << fpga_component << ":"
+ " Expecting " << uhd_major << ", got " << fpga_major << "."
+ ;
+ }
+ throw uhd::runtime_error(str(
+ boost::format("FPGA component `%s' is revision %d and UHD supports"
+ " revision %d. Please either upgrade UHD "
+ " (recommended) or downgrade the FPGA image.")
+ % fpga_component
+ % fpga_major
+ % uhd_major
+ ));
+
+ }
+ if (uhd_minor > fpga_minor) {
+ if (fail_on_minor_behind) {
+ if (!log_component.empty()) {
+ UHD_LOGGER_ERROR(log_component) << str(
+ boost::format("Minor compat number mismatch for `%s':"
+ " Expecting %d.%d, got %d.%d.")
+ % fpga_component
+ % uhd_major
+ % uhd_minor
+ % fpga_major
+ % fpga_minor
+ );
+ }
+ throw uhd::runtime_error(str(
+ boost::format("FPGA component `%s' is revision %d.%d and UHD supports"
+ " revision %d.%d. Please either upgrade UHD "
+ " (recommended) or downgrade the FPGA image.")
+ % fpga_component
+ % fpga_major
+ % fpga_minor
+ % uhd_major
+ % uhd_minor
+ ));
+ } else {
+ if (!log_component.empty()) {
+ UHD_LOGGER_WARNING(log_component) << str(
+ boost::format("Non-critical minor compat number mismatch "
+ "for `%s': Expecting %d.%d, got %d.%d.")
+ % fpga_component
+ % uhd_major
+ % uhd_minor
+ % fpga_major
+ % fpga_minor
+ );
+ }
+ }
+ } else if (uhd_minor < fpga_minor) {
+ if (!log_component.empty()) {
+ UHD_LOGGER_WARNING(log_component) << str(
+ boost::format("Non-critical minor compat number mismatch "
+ "for `%s': Expecting %d.%d, got %d.%d.")
+ % fpga_component
+ % uhd_major
+ % uhd_minor
+ % fpga_major
+ % fpga_minor
+ );
+ }
+ }
+ // We got here? Then all is good.
+}