Remove proto-RFNoC files

This commit removes all files and parts of files that are used by
proto-RFNoC only.

uhd: Fix include CMakeLists.txt, add missing files
This commit is contained in:
Martin Braun 2019-08-20 10:00:47 -07:00
parent 1ac6e6f561
commit 7d69dcdcc3
218 changed files with 244 additions and 22930 deletions

View File

@ -301,8 +301,6 @@ link_directories(${Boost_LIBRARY_DIRS})
########################################################################
# Additional settings for build environment
########################################################################
# Note: RFNoC never gets fully disabled, but the public APIs do
set(ENABLE_RFNOC ON CACHE BOOL "Export RFNoC includes and symbols")
include(UHDGlobalDefs)
include(UHDLog)
@ -470,12 +468,7 @@ endforeach(Boost_Comp)
if(ENABLE_USB)
list(APPEND UHD_LINK_LIST_STATIC "usb-1.0")
endif(ENABLE_USB)
# UHDConfig.cmake also needs UHD_RFNOC_FOUND
if(ENABLE_RFNOC)
set(UHD_RFNOC_FOUND "TRUE")
else()
set(UHD_RFNOC_FOUND "FALSE")
endif(ENABLE_RFNOC)
set(UHD_RFNOC_FOUND "TRUE")
configure_file(
${CMAKE_SOURCE_DIR}/cmake/Modules/UHDConfigVersion.cmake.in

View File

@ -16,10 +16,5 @@ else()
math(EXPR UHD_VERSION_ADDED "1000000 * ${UHD_VERSION_MAJOR} + 10000 * ${UHD_VERSION_API} + 100 * ${UHD_VERSION_ABI} + ${UHD_VERSION_PATCH}")
endif(UHD_VERSION_DEVEL)
## RFNoC
if(ENABLE_RFNOC)
add_definitions(-DUHD_RFNOC_ENABLED)
endif(ENABLE_RFNOC)
## make sure the code knows about config.h
add_definitions(-DHAVE_CONFIG_H)

View File

@ -37,9 +37,6 @@ if(ENABLE_MANUAL)
set(DOXYGEN_FPGA_MANUAL_REFERENCE "<a href=\"http://files.ettus.com/manual/md_fpga.html\">Part III: FPGA Manual</a>")
set(DOXYGEN_STRIP_EXTRA "")
set(DOXYGEN_EXCLUDE_DIRS "")
if(NOT ENABLE_RFNOC)
set(DOXYGEN_EXCLUDE_DIRS "${DOXYGEN_EXCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/include/uhd/rfnoc")
endif(NOT ENABLE_RFNOC)
# Now, check if we have the FPGA sources as well.
# If so, pull them in:
if(HAS_FPGA_SUBMODULE)
@ -73,7 +70,7 @@ if(ENABLE_DOXYGEN)
file(GLOB_RECURSE header_files ${CMAKE_SOURCE_DIR}/include/*.hpp)
file(GLOB_RECURSE h_files ${CMAKE_SOURCE_DIR}/include/*.h)
list(APPEND header_files ${h_files})
set(DOXYGEN_DEPENDENCIES ${DOXYGEN_DEPENDENCIES} ${header_files} "${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/gen_basic_funcs.py")
set(DOXYGEN_DEPENDENCIES ${DOXYGEN_DEPENDENCIES} ${header_files})
if(ENABLE_DOXYGEN_FULL)
set(DOXYGEN_INPUT_DIRS "${DOXYGEN_INPUT_DIRS} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/lib ${CMAKE_SOURCE_DIR}/python")
else(ENABLE_DOXYGEN_FULL)

View File

@ -1,16 +0,0 @@
/*! \page page_rfnoc_descriptor_file RFNoC Block Descriptor Files
\section rfnoc_descriptor_file_nocscript NocScript
NocScript is a simple DSL designed to augment block definition files for RFNoC.
\li Statically Typed
\li No implicit typecasting
\li Very few operators
See \subpage page_nocscript_funcs for a full function reference.
*/
// vim:ft=doxygen:

View File

@ -13,7 +13,6 @@ Follow these links to get to the section of the manual you wish to consult, or u
\li \subpage page_devices "Part I: Devices & Usage Manual"
\li \subpage page_uhd "Part II: UHD Development Manual"
\li @DOXYGEN_FPGA_MANUAL_REFERENCE@
\li \subpage page_rfnoc "Part IV: RFNoC Development Manual"
### Further Information

View File

@ -1,6 +0,0 @@
/*! \page page_rfnoc RFNoC Development Manual
\li \subpage page_rfnoc_descriptor_file
*/
// vim:ft=doxygen:

View File

@ -28,19 +28,13 @@ set(example_sources
latency_test.cpp
gpio.cpp
sync_to_gps.cpp
rfnoc_nullsource_ce_rx.cpp
rfnoc_rx_to_file.cpp
#rfnoc_radio_loopback.cpp
#benchmark_streamer.cpp
#replay_samples_from_file.cpp
)
if(ENABLE_RFNOC)
list(APPEND
example_sources
rfnoc_nullsource_ce_rx.cpp
rfnoc_rx_to_file.cpp
rfnoc_radio_loopback.cpp
replay_samples_from_file.cpp
benchmark_streamer.cpp
)
endif(ENABLE_RFNOC)
if(ENABLE_OCTOCLOCK)
list(APPEND example_sources test_clock_synch.cpp)
endif(ENABLE_OCTOCLOCK)

View File

@ -5,7 +5,6 @@
//
#include <uhd/convert.hpp>
#include <uhd/device3.hpp>
#include <uhd/rfnoc/block_ctrl.hpp>
#include <uhd/rfnoc/ddc_block_ctrl.hpp>
#include <uhd/rfnoc/duc_block_ctrl.hpp>

View File

@ -20,7 +20,6 @@
// crossbar (provided it has stream-through capabilities)
// and then streams the result to the host, writing it into a file.
#include <uhd/device3.hpp>
#include <uhd/exception.hpp>
#include <uhd/rfnoc/block_control.hpp>
#include <uhd/rfnoc/null_block_control.hpp>

View File

@ -8,7 +8,6 @@
// Example UHD/RFNoC application: Connect an rx radio to a tx radio and
// run a loopback.
#include <uhd/device3.hpp>
#include <uhd/rfnoc/radio_ctrl.hpp>
#include <uhd/utils/math.hpp>
#include <uhd/utils/safe_main.hpp>

View File

@ -1,13 +1,11 @@
#
# Copyright 2010-2011,2013-2015 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This is a temporary include - remove once rfnoc is replaced by erfnoc
add_subdirectory(erfnoc)
add_subdirectory(rfnoc)
add_subdirectory(transport)
add_subdirectory(types)
@ -35,14 +33,6 @@ UHD_INSTALL(FILES
COMPONENT headers
)
if(ENABLE_RFNOC)
UHD_INSTALL(FILES
device3.hpp
DESTINATION ${INCLUDE_DIR}/uhd
COMPONENT headers
)
endif(ENABLE_RFNOC)
if(ENABLE_C_API)
UHD_INSTALL(FILES
config.h

View File

@ -111,13 +111,6 @@ typedef ptrdiff_t ssize_t;
# endif // UHD_DLL_EXPORTS
#endif // UHD_STATIC_LIB
#ifdef UHD_RFNOC_ENABLED
# define UHD_RFNOC_API UHD_API
#else
# define UHD_RFNOC_API
#endif // UHD_RFNOC_ENABLED
// Platform defines for conditional parts of headers:
// Taken from boost/config/select_platform_config.hpp,
// however, we define macros, not strings for platforms.

View File

@ -1,145 +0,0 @@
//
// Copyright 2014-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_UHD_DEVICE3_HPP
#define INCLUDED_UHD_DEVICE3_HPP
#include <uhd/device.hpp>
#include <uhd/rfnoc/block_ctrl_base.hpp>
#include <uhd/rfnoc/graph.hpp>
#include <boost/core/demangle.hpp>
#include <boost/thread/mutex.hpp>
#include <vector>
namespace uhd {
/*!
* \brief Extends uhd::device for third-generation USRP devices.
*
* Generation-3 devices are characterized by the following traits:
* - They support RFNoC (RF Network-on-Chip).
* - Data transport uses the compressed VITA (CVITA/CHDR) data format.
*/
class UHD_API device3 : public uhd::device
{
public:
typedef boost::shared_ptr<device3> sptr;
//! Same as uhd::device::make(), but will fail if not actually a device3
static sptr make(const device_addr_t& hint, const size_t which = 0);
virtual rfnoc::graph::sptr create_graph(const std::string& name = "") = 0;
/*! Reset blocks after a stream.
*
* TODO write docs
*/
void clear();
/*! \brief Checks if an RFNoC block exists on the device.
*
* \param block_id Canonical block name (e.g. "0/FFT_1").
* \return true if a block with the specified id exists
* \note this access is not thread safe if peformed during block enumeration
*/
bool has_block(const rfnoc::block_id_t& block_id) const;
/*! Same as has_block(), but with a type check.
*
* \return true if a block of type T with the specified id exists
* \note this access is not thread safe if peformed during block enumeration
*/
template <typename T> bool has_block(const rfnoc::block_id_t& block_id) const
{
if (has_block(block_id)) {
return bool(boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id)));
} else {
return false;
}
}
/*! \brief Returns a block controller class for an RFNoC block.
*
* If the given block ID is not valid (i.e. such a block does not exist
* on this device), it will throw a uhd::lookup_error.
*
* \param block_id Canonical block name (e.g. "0/FFT_1").
* \note this access is not thread safe if peformed during block enumeration
*/
rfnoc::block_ctrl_base::sptr get_block_ctrl(const rfnoc::block_id_t& block_id) const;
/*! Same as get_block_ctrl(), but with a type cast.
*
* If you have a block controller class that is derived from block_ctrl_base,
* use this function to access its specific methods.
* If the given block ID is not valid (i.e. such a block does not exist
* on this device) or if the type does not match, it will throw a uhd::lookup_error.
*
* \code{.cpp}
* // Assume DEV is a device3::sptr
* uhd::rfnoc::my_block_ctrl::sptr block_controller =
* get_block_ctrl<my_block_ctrl>("0/MyBlock_0");
* block_controller->my_own_block_method();
* \endcode
* \note this access is not thread safe if peformed during block enumeration
*/
template <typename T>
boost::shared_ptr<T> get_block_ctrl(const rfnoc::block_id_t& block_id) const
{
boost::shared_ptr<T> blk =
boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id));
if (blk) {
return blk;
} else {
throw uhd::lookup_error(str(
boost::format("This device does not have a block of type %s with ID: %s")
% boost::core::demangle(typeid(T).name()) % block_id.to_string()));
}
}
/*! Returns the block ids of all blocks that match the specified hint
* Uses block_ctrl_base::match() internally.
* If no matching block is found, it returns an empty vector.
*
* To access specialized block controller classes (i.e. derived from block_ctrl_base),
* use the templated version of this function, e.g.
* \code{.cpp}
* // Assume DEV is a device3::sptr
* null_block_ctrl::sptr null_block =
* DEV->find_blocks<null_block_ctrl>("NullSrcSink"); \endcode \note this access is not
* thread safe if peformed during block enumeration
*/
std::vector<rfnoc::block_id_t> find_blocks(const std::string& block_id_hint) const;
/*! Type-cast version of find_blocks().
*/
template <typename T>
std::vector<rfnoc::block_id_t> find_blocks(const std::string& block_id_hint) const
{
std::vector<rfnoc::block_id_t> all_block_ids = find_blocks(block_id_hint);
std::vector<rfnoc::block_id_t> filt_block_ids;
for (size_t i = 0; i < all_block_ids.size(); i++) {
if (has_block<T>(all_block_ids[i])) {
filt_block_ids.push_back(all_block_ids[i]);
}
}
return filt_block_ids;
}
protected:
//! List of *all* RFNoC blocks available on this device.
// It is the responsibility of the deriving class to make
// sure this gets correctly populated.
std::vector<rfnoc::block_ctrl_base::sptr> _rfnoc_block_ctrl;
//! Mutex to protect access to members
boost::mutex _block_ctrl_mutex;
};
} // namespace uhd
#endif /* INCLUDED_UHD_DEVICE3_HPP */

View File

@ -1,8 +0,0 @@
#
# Copyright 2019 Ettus Research, a National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
add_subdirectory(blocks)
add_subdirectory(core)

View File

@ -1,20 +0,0 @@
#
# Copyright 2019 Ettus Research, a National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
file(GLOB yml_files "*.yml")
file(GLOB json_files "*.json")
# We always need this, even when RFNoC is 'disabled'
UHD_INSTALL(
FILES ${yml_files}
DESTINATION ${PKG_DATA_DIR}/erfnoc/core
COMPONENT headers # TODO: Different component
)
UHD_INSTALL(
FILES ${json_files}
DESTINATION ${PKG_DATA_DIR}/erfnoc/core
COMPONENT headers # TODO: Different component
)

View File

@ -1,58 +1,45 @@
#
# Copyright 2014-2016 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
if(ENABLE_RFNOC)
UHD_INSTALL(FILES
# Infrastructure
block_ctrl_base.hpp
block_ctrl.hpp
block_control.hpp
blockdef.hpp
block_id.hpp
constants.hpp
defaults.hpp
dirtifier.hpp
graph.hpp
graph_edge.hpp
mb_controller.hpp
noc_block_make_args.hpp
node_ctrl_base.hpp
node_ctrl_base.ipp
node.hpp
node.ipp
rate_node_ctrl.hpp
registry.hpp
scalar_node_ctrl.hpp
sink_block_ctrl_base.hpp
sink_node_ctrl.hpp
source_block_ctrl_base.hpp
source_node_ctrl.hpp
stream_sig.hpp
terminator_node_ctrl.hpp
tick_node_ctrl.hpp
# Block controllers
ddc_block_control.hpp
duc_block_control.hpp
ddc_block_ctrl.hpp
dma_fifo_block_ctrl.hpp
duc_block_ctrl.hpp
fir_block_ctrl.hpp
null_block_ctrl.hpp
null_block_control.hpp
radio_ctrl.hpp
radio_control.hpp
replay_block_ctrl.hpp
siggen_block_ctrl.hpp
window_block_ctrl.hpp
register_iface.hpp
DESTINATION ${INCLUDE_DIR}/uhd/rfnoc
COMPONENT headers
)
endif(ENABLE_RFNOC)
add_subdirectory(blocks)
#add_subdirectory(components)
UHD_INSTALL(FILES
# Infrastructure
actions.hpp
block_id.hpp
blockdef.hpp
constants.hpp
defaults.hpp
dirtifier.hpp
filter_node.hpp
graph_edge.hpp
mb_controller.hpp
noc_block_base.hpp
noc_block_make_args.hpp
node.hpp
node.ipp
property.hpp
property.ipp
radio_control.hpp
register_iface.hpp
register_iface_holder.hpp
registry.hpp
res_source_info.hpp
traffic_counter.hpp
# Block controllers
block_control.hpp
ddc_block_control.hpp
duc_block_control.hpp
null_block_control.hpp
radio_control.hpp
DESTINATION ${INCLUDE_DIR}/uhd/rfnoc
COMPONENT headers
)
add_subdirectory(blocks)
add_subdirectory(core)

View File

@ -1,36 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief This is the default implementation of a block_ctrl_base.
*
* For most blocks, this will be a sufficient implementation. All registers
* can be set by sr_write(). The default behaviour of functions is documented
* in uhd::rfnoc::block_ctrl_base.
*/
class UHD_RFNOC_API block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base
{
public:
// Required macro in RFNoC block classes
UHD_RFNOC_BLOCK_OBJECT(block_ctrl)
// Nothing else here -- all function definitions are in block_ctrl_base,
// source_block_ctrl_base and sink_block_ctrl_base
}; /* class block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP */

View File

@ -1,436 +0,0 @@
//
// Copyright 2014-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP
#include <uhd/property_tree.hpp>
#include <uhd/rfnoc/block_id.hpp>
#include <uhd/rfnoc/blockdef.hpp>
#include <uhd/rfnoc/constants.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/rfnoc/stream_sig.hpp>
#include <uhd/stream.hpp>
#include <uhd/types/sid.hpp>
#include <uhd/types/stream_cmd.hpp>
#include <uhd/types/wb_iface.hpp>
#include <uhd/utils/static.hpp>
#include <stdint.h>
#include <boost/shared_ptr.hpp>
namespace uhd { namespace rfnoc {
// Forward declarations
class ctrl_iface;
namespace nocscript {
class block_iface;
}
// TODO: Move this out of public section
struct make_args_t
{
make_args_t(const std::string& key = "")
: device_index(0), block_name(""), block_key(key)
{
}
//! A valid interface that allows us to read and write registers
std::map<size_t, boost::shared_ptr<ctrl_iface> > ctrl_ifaces;
//! This block's base address (address of block port 0)
uint32_t base_address;
//! The device index (or motherboard index).
size_t device_index;
//! A property tree for this motherboard. Example: If the root a device's
// property tree is /mboards/0, pass a subtree starting at /mboards/0
// to the constructor.
uhd::property_tree::sptr tree;
//! The name of the block as it will be addressed
std::string block_name;
//! The key of the block, i.e. how it was registered
std::string block_key;
};
//! This macro must be put in the public section of an RFNoC
// block class
#define UHD_RFNOC_BLOCK_OBJECT(class_name) typedef boost::shared_ptr<class_name> sptr;
//! Shorthand for block constructor
#define UHD_RFNOC_BLOCK_CONSTRUCTOR(CLASS_NAME) \
CLASS_NAME##_impl(const make_args_t& make_args) : block_ctrl_base(make_args)
//! This macro must be placed inside a block implementation file
// after the class definition
#define UHD_RFNOC_BLOCK_REGISTER(CLASS_NAME, BLOCK_NAME) \
block_ctrl_base::sptr CLASS_NAME##_make(const make_args_t& make_args) \
{ \
return block_ctrl_base::sptr(new CLASS_NAME##_impl(make_args)); \
} \
UHD_STATIC_BLOCK(register_rfnoc_##CLASS_NAME) \
{ \
uhd::rfnoc::block_ctrl_base::register_block(&CLASS_NAME##_make, BLOCK_NAME); \
}
/*! \brief Base class for all RFNoC block controller objects.
*
* For RFNoC, block controller objects must be derived from
* uhd::rfnoc::block_ctrl_base. This class provides all functions
* that a block *must* provide. Typically, you would not derive
* a block controller class directly from block_ctrl_base, but
* from a class such as uhd::usrp::rfnoc::source_block_ctrl_base or
* uhd::usrp::rfnoc::sink_block_ctrl_base which extends its functionality.
*/
class UHD_RFNOC_API block_ctrl_base;
class block_ctrl_base : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<block_ctrl_base> sptr;
typedef boost::function<sptr(const make_args_t&)> make_t;
/***********************************************************************
* Factory functions
**********************************************************************/
/*! Register a block controller class into the discovery and factory system.
*
* Note: It is not recommended to call this function directly.
* Rather, use the UHD_RFNOC_BLOCK_REGISTER() macro, which will set up
* the discovery and factory system correctly.
*
* \param make A factory function that makes a block controller object
* \param name A unique block name, e.g. 'FFT'. If a block has this block name,
* it will use \p make to generate the block controller class.
*/
static void register_block(const make_t& make, const std::string& name);
/*!
* \brief Create a block controller class given a NoC-ID or a block name.
*
* If a block name is given in \p make_args, it will directly try to
* generate a block of this type. If no block name is given, it will
* look up a name using the NoC-ID and use that.
* If it can't find a suitable block controller class, it will generate
* a uhd::rfnoc::block_ctrl. However, if a block name *is* specified,
* it will throw a uhd::runtime_error if this block type is not registered.
*
* \param make_args Valid make args.
* \param noc_id The 64-Bit NoC-ID.
* \return a shared pointer to a new device instance
*/
static sptr make(const make_args_t& make_args, uint64_t noc_id = ~0);
/***********************************************************************
* Block Communication and Control
*
* These functions do not require communication with the FPGA.
**********************************************************************/
/*! Returns the 16-Bit address for this block.
*/
uint32_t get_address(size_t block_port = 0);
/*! Returns the unique block ID for this block (e.g. "0/FFT_1").
*/
block_id_t get_block_id() const
{
return _block_id;
};
/*! Shorthand for get_block_id().to_string()
*/
std::string unique_id() const
{
return _block_id.to_string();
};
/***********************************************************************
* FPGA control & communication
**********************************************************************/
/*! Returns a list of valid ports that can be used for sr_write(), sr_read() etc.
*/
std::vector<size_t> get_ctrl_ports() const;
/*! Allows setting one register on the settings bus.
*
* Note: There is no address translation ("memory mapping") necessary.
* Register 0 is 0, 1 is 1 etc.
*
* \param reg The settings register to write to.
* \param data New value of this register.
* \param port Port on which to write
*/
void sr_write(const uint32_t reg, const uint32_t data, const size_t port = 0);
/*! Allows setting one register on the settings bus.
*
* Like sr_write(), but takes a register name as argument.
*
* \param reg The settings register to write to.
* \param data New value of this register.
* \param port Port on which to write
* \throw uhd::key_error if \p reg is not a valid register name
*
*/
void sr_write(const std::string& reg, const uint32_t data, const size_t port = 0);
/*! Allows reading one register on the settings bus (64-Bit version).
*
* \param reg The settings register to be read.
* \param port Port on which to read
*
* Returns the readback value.
*/
uint64_t sr_read64(const settingsbus_reg_t reg, const size_t port = 0);
/*! Allows reading one register on the settings bus (32-Bit version).
*
* \param reg The settings register to be read.
* \param port Port on which to read
*
* Returns the readback value.
*/
uint32_t sr_read32(const settingsbus_reg_t reg, const size_t port = 0);
/*! Allows reading one user-defined register (64-Bit version).
*
* This is a shorthand for setting the requested address
* through sr_write() and then reading SR_READBACK_REG_USER
* with sr_read64().
*
* \param addr The user register address.
* \param port Port on which to read
* \returns the readback value.
*/
uint64_t user_reg_read64(const uint32_t addr, const size_t port = 0);
/*! Allows reading one user-defined register (64-Bit version).
*
* Identical to user_reg_read64(), but takes a register name
* instead of a numeric address. The register name must be
* defined in the block definition file.
*
* \param reg The user register address.
* \param port Port on which to read
* \returns the readback value.
* \throws uhd::key_error if \p reg is not a valid register name
*/
uint64_t user_reg_read64(const std::string& reg, const size_t port = 0);
/*! Allows reading one user-defined register (32-Bit version).
*
* This is a shorthand for setting the requested address
* through sr_write() and then reading SR_READBACK_REG_USER
* with sr_read32().
*
* \param addr The user register address.
* \param port Port on which to read
* \returns the readback value.
*/
uint32_t user_reg_read32(const uint32_t addr, const size_t port = 0);
/*! Allows reading one user-defined register (32-Bit version).
*
* Identical to user_reg_read32(), but takes a register name
* instead of a numeric address. The register name must be
* defined in the block definition file.
*
* \param reg The user register name.
* \param port Destination port from which to read.
* \returns the readback value.
* \throws uhd::key_error if \p reg is not a valid register name
*/
uint32_t user_reg_read32(const std::string& reg, const size_t port = 0);
/*! Sets a command time for all future command packets.
*
* \throws uhd::assertion_error if the underlying interface does not
* actually support timing.
*/
void set_command_time(const time_spec_t& time_spec, const size_t port = ANY_PORT);
/*! Returns the current command time for all future command packets.
*
* \returns the command time as a time_spec_t.
*/
time_spec_t get_command_time(const size_t port = 0);
/*! Sets a tick rate for the command timebase.
*
* \param tick_rate The tick rate in Hz
* \param port Port
*/
void set_command_tick_rate(const double tick_rate, const size_t port = ANY_PORT);
/*! Resets the command time.
* Any command packet after this call will no longer have a time associated
* with it.
*
* \throws uhd::assertion_error if the underlying interface does not
* actually support timing.
*/
void clear_command_time(const size_t port);
/*! Reset block after streaming operation.
*
* This does the following:
* - Reset flow control (sequence numbers etc.)
* - Clear the list of connected blocks
*
* Internally, rfnoc::node_ctrl_base::clear() and _clear() are called
* (in that order).
*
* Between runs, it can be necessary to call this method,
* or blocks might be left hanging in a streaming state, and can get
* confused when a new application starts.
*
* For custom behaviour, overwrite _clear(). If you do so, you must take
* take care of resetting flow control yourself.
*
* TODO: Find better name (it disconnects, clears FC...)
*/
void clear();
/***********************************************************************
* Argument handling
**********************************************************************/
/*! Set multiple block args. Calls set_arg() for all individual items.
*
* Note that this function will silently ignore any keys in \p args that
* aren't already registered as block arguments.
*/
void set_args(const uhd::device_addr_t& args, const size_t port = 0);
//! Set a specific block argument. \p val is converted to the corresponding
// data type using by looking up its type in the block definition.
void set_arg(const std::string& key, const std::string& val, const size_t port = 0);
//! Direct access to set a block argument.
template <typename T>
void set_arg(const std::string& key, const T& val, const size_t port = 0)
{
_tree->access<T>(get_arg_path(key, port) / "value").set(val);
}
//! Return all block arguments as a device_addr_t.
uhd::device_addr_t get_args(const size_t port = 0) const;
//! Return a single block argument in string format.
std::string get_arg(const std::string& key, const size_t port = 0) const;
//! Direct access to get a block argument.
template <typename T>
T get_arg(const std::string& key, const size_t port = 0) const
{
return _tree->access<T>(get_arg_path(key, port) / "value").get();
}
std::string get_arg_type(const std::string& key, const size_t port = 0) const;
protected:
/***********************************************************************
* Structors
**********************************************************************/
block_ctrl_base(void){}; // To allow pure virtual (interface) sub-classes
virtual ~block_ctrl_base();
/*! Constructor. This is only called from the internal block factory!
*
* \param make_args All arguments to this constructor are passed in this object.
* Its details are subject to change. Use the
* UHD_RFNOC_BLOCK_CONSTRUCTOR() macro to set up your block's constructor in a
* portable fashion.
*/
block_ctrl_base(const make_args_t& make_args);
/***********************************************************************
* Helpers
**********************************************************************/
stream_sig_t _resolve_port_def(const blockdef::port_t& port_def) const;
//! Return the property tree path to a block argument \p key on \p port
uhd::fs_path get_arg_path(const std::string& key, size_t port = 0) const
{
return _root_path / "args" / port / key;
};
//! Get a control interface object for block port \p block_port
timed_wb_iface::sptr get_ctrl_iface(const size_t block_port);
/***********************************************************************
* Hooks & Derivables
**********************************************************************/
//! Override this function if your block does something else
// than reset register SR_CLEAR_TX_FC.
virtual void _clear(const size_t port = 0);
//! Override this function if your block needs to specially handle
// setting the command time
virtual void _set_command_time(
const time_spec_t& time_spec, const size_t port = ANY_PORT);
/***********************************************************************
* Protected members
**********************************************************************/
//! Property sub-tree
uhd::property_tree::sptr _tree;
//! Root node of this block's properties
uhd::fs_path _root_path;
//! Block definition (stores info about the block such as ports)
blockdef::sptr _block_def;
private:
//! Helper function to initialize the port definition nodes in the prop tree
void _init_port_defs(const std::string& direction,
blockdef::ports_t ports,
const size_t first_port_index = 0);
//! Helper function to initialize the block args (used by ctor only)
void _init_block_args();
//! Helper to create a lambda to read tick rate
double get_command_tick_rate(const size_t port);
//! Helper to start flushing for this block
void _start_drain(const size_t port = 0);
//! Helper to flush any in-flight packets for this block
bool _flush(const size_t port = 0);
/***********************************************************************
* Private members
**********************************************************************/
//! Objects to actually send and receive the commands
std::map<size_t, boost::shared_ptr<ctrl_iface> > _ctrl_ifaces;
std::map<size_t, time_spec_t> _cmd_timespecs;
std::map<size_t, double> _cmd_tickrates;
//! The base address of this block (the address of block port 0)
uint32_t _base_address;
//! 64-bit NoC ID of this block
uint64_t _noc_id;
//! noc_shell compat number, as one 64-bit number [major,minor]
uint64_t _compat_num;
//! The (unique) block ID.
block_id_t _block_id;
//! Interface to NocScript parser
boost::shared_ptr<nocscript::block_iface> _nocscript_iface;
}; /* class block_ctrl_base */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP */

View File

@ -37,7 +37,7 @@ namespace rfnoc {
*
* This class can represent these block IDs.
*/
class UHD_RFNOC_API block_id_t
class UHD_API block_id_t
{
public:
block_id_t();

View File

@ -19,7 +19,7 @@ namespace uhd { namespace rfnoc {
/*! Reads and stores block definitions for blocks and components.
*/
class UHD_RFNOC_API blockdef : public boost::enable_shared_from_this<blockdef>
class UHD_API blockdef : public boost::enable_shared_from_this<blockdef>
{
public:
typedef boost::shared_ptr<blockdef> sptr;

View File

@ -1,15 +1,14 @@
#
# Copyright 2014-2016 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
# Copyright 2019 Ettus Research, a National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
file(GLOB xml_files "*.xml")
file(GLOB yml_files "*.yml")
# We always need this, even when RFNoC is 'disabled'
UHD_INSTALL(
FILES ${xml_files}
FILES ${yml_files}
DESTINATION ${PKG_DATA_DIR}/rfnoc/blocks
COMPONENT headers # TODO: Different component
)

View File

@ -1,50 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<!--The Adder & Subtractor takes inputs from Block Ports 0 & 1 and-->
<!--outputs the addition / subtraction of the values on Block Ports 0 & 1.-->
<!--- Block Port 0 + Block Port 1 => Block Port 0-->
<!--- Block Port 0 - Block Port 1 => Block Port 1-->
<name>Adder &amp; Subtractor</name>
<blockname>AddSub</blockname>
<ids>
<id revision="0">ADD0</id>
</ids>
<!--Order matters. The first listed port is port 0, etc.-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
<port>0</port>
</sink>
<sink>
<name>in1</name>
<type>sc16</type>
<port>1</port>
</sink>
<source>
<name>sum</name>
<type>sc16</type>
</source>
<source>
<name>diff</name>
<type>sc16</type>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,17 +0,0 @@
<!--Default XML file-->
<nocblock>
<name>Block</name>
<blockname>Block</blockname>
<ids>
<id revision="0">FFFFFFFFFFFFFFFF</id>
</ids>
<!--One input, one output. If this is used, better have all the info the C++ file.-->
<ports>
<sink>
<name>in</name>
</sink>
<source>
<name>out</name>
</source>
</ports>
</nocblock>

View File

@ -1,154 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Rx DSP (DDC/CORDIC)</name>
<blockname>DDC</blockname>
<key>DDC</key>
<!--There can be several of these:-->
<ids>
<id revision="0">DDC0000000000000</id>
</ids>
<!-- Registers -->
<registers>
<!-- AXI rate change block registers -->
<setreg>
<name>N</name>
<address>128</address>
</setreg>
<setreg>
<name>M</name>
<address>129</address>
</setreg>
<setreg>
<!-- 1 bit, enable clear user -->
<name>CONFIG</name>
<address>130</address>
</setreg>
<!-- DDC block registers -->
<setreg>
<!-- DDS phase increment word -->
<name>DDS_FREQ</name>
<address>132</address>
</setreg>
<setreg>
<!-- Scaling factor to compensate for gain through filters and CORDIC -->
<name>SCALE_IQ</name>
<address>133</address>
</setreg>
<setreg>
<!-- DDC control word, 10 bits total, 2 bits for Halfbands, 8 bits for CIC rate -->
<name>DECIM_WORD</name>
<address>134</address>
</setreg>
<setreg>
<!-- Real mode, swap IQ -->
<name>MODE</name>
<address>135</address>
</setreg>
<setreg>
<!-- Filter coefficients reload -->
<name>RELOAD</name>
<address>136</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>0</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>1</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<sink>
<name>in1</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<source>
<name>out1</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,331 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>EISCAT Rx DSP (DDC/CORDIC)</name>
<blockname>DDC</blockname>
<key>DDC</key>
<!--There can be several of these:-->
<ids>
<id revision="0">DDC5E15CA7000000</id>
</ids>
<!-- Registers -->
<registers>
<!-- AXI rate change block registers -->
<setreg>
<name>N</name>
<address>128</address>
</setreg>
<setreg>
<name>M</name>
<address>129</address>
</setreg>
<setreg>
<!-- 1 bit, enable clear user -->
<name>CONFIG</name>
<address>130</address>
</setreg>
<!-- DDC block registers -->
<setreg>
<!-- DDS phase increment word -->
<name>DDS_FREQ</name>
<address>132</address>
</setreg>
<setreg>
<!-- Scaling factor to compensate for gain through filters and CORDIC -->
<name>SCALE_IQ</name>
<address>133</address>
</setreg>
<setreg>
<!-- DDC control word, 10 bits total, 2 bits for Halfbands, 8 bits for CIC rate -->
<name>DECIM_WORD</name>
<address>134</address>
</setreg>
<setreg>
<!-- Real mode, swap IQ -->
<!-- Real mode = bit 1, swap IQ = bit 0 -->
<name>MODE</name>
<address>135</address>
</setreg>
<setreg>
<!-- Filter coefficients reload -->
<name>RELOAD</name>
<address>136</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>0</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>mode</name>
<type>int</type>
<value>2</value>
<port>0</port>
<action>SR_WRITE("MODE", $mode)</action>
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>1</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>mode</name>
<type>int</type>
<value>2</value>
<port>1</port>
<action>SR_WRITE("MODE", $mode)</action>
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>2</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>mode</name>
<type>int</type>
<value>2</value>
<port>2</port>
<action>SR_WRITE("MODE", $mode)</action>
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>2</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>2</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>2</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>2</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>3</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>mode</name>
<type>int</type>
<value>2</value>
<port>3</port>
<action>SR_WRITE("MODE", $mode)</action>
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>3</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>3</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>3</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>3</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>4</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>mode</name>
<type>int</type>
<value>2</value>
<port>4</port>
<action>SR_WRITE("MODE", $mode)</action>
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>4</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>4</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>4</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>4</port>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>s16</type>
</sink>
<sink>
<name>in1</name>
<type>s16</type>
</sink>
<sink>
<name>in2</name>
<type>s16</type>
</sink>
<sink>
<name>in3</name>
<type>s16</type>
</sink>
<sink>
<name>in4</name>
<type>s16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<source>
<name>out1</name>
<type>sc16</type>
</source>
<source>
<name>out2</name>
<type>sc16</type>
</source>
<source>
<name>out3</name>
<type>sc16</type>
</source>
<source>
<name>out4</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,117 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Rx DSP (DDC/CORDIC)</name>
<blockname>DDC</blockname>
<key>DDC</key>
<!--There can be several of these:-->
<ids>
<id revision="0">DDC0000000000001</id>
</ids>
<!-- Registers -->
<registers>
<!-- AXI rate change block registers -->
<setreg>
<name>N</name>
<address>128</address>
</setreg>
<setreg>
<name>M</name>
<address>129</address>
</setreg>
<setreg>
<!-- 1 bit, enable clear user -->
<name>CONFIG</name>
<address>130</address>
</setreg>
<!-- DDC block registers -->
<setreg>
<!-- DDS phase increment word -->
<name>DDS_FREQ</name>
<address>132</address>
</setreg>
<setreg>
<!-- Scaling factor to compensate for gain through filters and CORDIC -->
<name>SCALE_IQ</name>
<address>133</address>
</setreg>
<setreg>
<!-- DDC control word, 10 bits total, 2 bits for Halfbands, 8 bits for CIC rate -->
<name>DECIM_WORD</name>
<address>134</address>
</setreg>
<setreg>
<!-- Real mode, swap IQ -->
<name>MODE</name>
<address>135</address>
</setreg>
<setreg>
<!-- Filter coefficients reload -->
<name>RELOAD</name>
<address>136</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>0</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($fullscale, 0.0)</check>
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>1</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,49 +0,0 @@
<nocblock>
<name>Debug</name>
<blockname>Debug</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">DEB1200000000000</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>CONFIG</name>
<address>128</address>
</setreg>
<setreg>
<name>PAYLOAD_SIZE</name>
<address>129</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>config</name>
<type>int</type>
<value>0</value>
<action>SR_WRITE("CONFIG", $config)</action>
</arg>
<arg>
<name>spp</name>
<type>int</type>
<value>64</value>
<action>SR_WRITE("PAYLOAD_SIZE", $spp)</action>
</arg>
</args>
<!-- Ports -->
<ports>
<sink>
<name>in</name>
<type>sc16</type>
</sink>
<source>
<name>out</name>
<type>sc16</type>
</source>
<source>
<name>stats</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,39 +0,0 @@
<nocblock>
<name>Digital Gain</name>
<blockname>DigitalGain</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">B160</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>GAIN</name>
<address>128</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<check>GE($gain, 0.0) AND LE($gain, 32767.0)</check>
<check_message>Invalid gain.</check_message>
<action>
SR_WRITE("GAIN", IROUND($gain))
</action>
</arg>
</args>
<!-- Ports -->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,64 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>DMA FIFO</name>
<blockname>DmaFIFO</blockname>
<key>DmaFIFO</key>
<!--There can be several of these:-->
<ids>
<id revision="0">F1F0D00000000000</id>
</ids>
<!-- Registers -->
<registers>
</registers>
<!-- Args -->
<args>
<arg>
<name>base_addr</name>
<type>int</type>
<!--<value>0</value>-->
<port>0</port>
<check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
<check_message>The base address must be 0 or a positive power of 2.</check_message>
</arg>
<arg>
<name>depth</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>0</port>
<check>IS_PWR_OF_2($depth)</check>
<check_message>The FIFO depth must be a positive power of 2.</check_message>
</arg>
<arg>
<name>base_addr</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>1</port>
<check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
<check_message>The base address must be 0 or a positive power of 2.</check_message>
</arg>
<arg>
<name>depth</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>1</port>
<check>IS_PWR_OF_2($depth)</check>
<check_message>The FIFO depth must be a positive power of 2.</check_message>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
</sink>
<sink>
<name>in1</name>
</sink>
<source>
<name>out0</name>
</source>
<source>
<name>out1</name>
</source>
</ports>
</nocblock>

View File

@ -1,109 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>DMA FIFO</name>
<blockname>DmaFIFO</blockname>
<key>DmaFIFO</key>
<!--There can be several of these:-->
<ids>
<id revision="0">F1F0D00000000004</id>
</ids>
<!-- Registers -->
<registers>
</registers>
<!-- Args -->
<args>
<arg>
<name>base_addr</name>
<type>int</type>
<!--<value>0</value>-->
<port>0</port>
<check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
<check_message>The base address must be 0 or a positive power of 2.</check_message>
</arg>
<arg>
<name>depth</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>0</port>
<check>IS_PWR_OF_2($depth)</check>
<check_message>The FIFO depth must be a positive power of 2.</check_message>
</arg>
<arg>
<name>base_addr</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>1</port>
<check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
<check_message>The base address must be 0 or a positive power of 2.</check_message>
</arg>
<arg>
<name>depth</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>1</port>
<check>IS_PWR_OF_2($depth)</check>
<check_message>The FIFO depth must be a positive power of 2.</check_message>
</arg>
<arg>
<name>base_addr</name>
<type>int</type>
<!--<value>67108864</value>-->
<port>2</port>
<check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
<check_message>The base address must be 0 or a positive power of 2.</check_message>
</arg>
<arg>
<name>depth</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>2</port>
<check>IS_PWR_OF_2($depth)</check>
<check_message>The FIFO depth must be a positive power of 2.</check_message>
</arg>
<arg>
<name>base_addr</name>
<type>int</type>
<!--<value>100663296</value>-->
<port>3</port>
<check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
<check_message>The base address must be 0 or a positive power of 2.</check_message>
</arg>
<arg>
<name>depth</name>
<type>int</type>
<!--<value>33554432</value>-->
<port>3</port>
<check>IS_PWR_OF_2($depth)</check>
<check_message>The FIFO depth must be a positive power of 2.</check_message>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
</sink>
<sink>
<name>in1</name>
</sink>
<sink>
<name>in2</name>
</sink>
<sink>
<name>in3</name>
</sink>
<source>
<name>out0</name>
</source>
<source>
<name>out1</name>
</source>
<source>
<name>out2</name>
</source>
<source>
<name>out3</name>
</source>
</ports>
</nocblock>

View File

@ -1,145 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Tx DSP (DUC/CORDIC)</name>
<blockname>DUC</blockname>
<key>DUC</key>
<!--There can be several of these:-->
<ids>
<id revision="0">D0C0000000000002</id>
</ids>
<!-- Registers -->
<registers>
<!-- AXI rate change block registers -->
<setreg>
<name>N</name>
<address>128</address>
</setreg>
<setreg>
<name>M</name>
<address>129</address>
</setreg>
<setreg>
<!-- 1 bit, enable clear user -->
<name>CONFIG</name>
<address>130</address>
</setreg>
<!-- DUC block registers -->
<setreg>
<name>INTERP_WORD</name> <!--Includes the half-bands and the CIC-->
<address>131</address>
</setreg>
<setreg>
<name>DDS_FREQ</name>
<address>132</address>
</setreg>
<setreg>
<name>SCALE_IQ</name>
<address>133</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>0</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($fullscale, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
</arg>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>1</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
<check>GE($fullscale, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<sink>
<name>in1</name>
<type>sc16</type>
</sink>
<source>
<name>out1</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,96 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Tx DSP (DUC/CORDIC)</name>
<blockname>DUC</blockname>
<key>DUC</key>
<!--There can be several of these:-->
<ids>
<id revision="0">D0C0000000000000</id>
</ids>
<!-- Registers -->
<registers>
<!-- AXI rate change block registers -->
<setreg>
<name>N</name>
<address>128</address>
</setreg>
<setreg>
<name>M</name>
<address>129</address>
</setreg>
<setreg>
<!-- 1 bit, enable clear user -->
<name>CONFIG</name>
<address>130</address>
</setreg>
<!-- DUC block registers -->
<setreg>
<name>INTERP_WORD</name> <!--Includes the half-bands and the CIC-->
<address>131</address>
</setreg>
<setreg>
<name>DDS_FREQ</name>
<address>132</address>
</setreg>
<setreg>
<name>SCALE_IQ</name>
<address>133</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>freq</name>
<type>double</type>
<value>0.0</value>
<port>0</port>
<!--<action>-->
<!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
<!--</action>-->
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>input_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($input_rate, 0.0)</check>
<check_message>The input rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>output_rate</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($output_rate, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
</arg>
<arg>
<name>fullscale</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
<check>GE($fullscale, 0.0)</check>
<check_message>The output rate must be a positive value (in Hz).</check_message>
<!--FIXME Calculate this properly-->
</arg>
<arg>
<name>scalar_correction</name>
<type>double</type>
<value>1.0</value>
<port>0</port>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in</name>
<type>sc16</type>
</sink>
<source>
<name>out</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,147 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>FFT</name>
<blockname>FFT</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">FF70</id>
</ids>
<!-- Registers -->
<registers>
<!--Note: AXI config bus uses 129 & 130-->
<setreg>
<name>FFT_RESET</name>
<address>131</address>
</setreg>
<setreg>
<name>FFT_SIZE_LOG2</name>
<address>132</address>
</setreg>
<setreg>
<name>MAGNITUDE_OUT</name>
<address>133</address>
</setreg>
<setreg>
<name>FFT_DIRECTION</name>
<address>134</address>
</setreg>
<setreg>
<name>FFT_SCALING</name>
<address>135</address>
</setreg>
<setreg>
<name>FFT_SHIFT_CONFIG</name>
<address>136</address>
</setreg>
<readback>
<name>RB_FFT_RESET</name>
<address>0</address>
</readback>
<readback>
<name>RB_MAGNITUDE_OUT</name>
<address>1</address>
</readback>
<readback>
<name>RB_FFT_SIZE_LOG2</name>
<address>2</address>
</readback>
<readback>
<name>RB_FFT_DIRECTION</name>
<address>3</address>
</readback>
<readback>
<name>RB_FFT_SCALING</name>
<address>4</address>
</readback>
<readback>
<name>RB_FFT_SHIFT_CONFIG</name>
<address>5</address>
</readback>
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>256</value>
<check>GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)</check>
<check_message>FFT size must be in [16, 4096] and a power of two.</check_message>
<action>SR_WRITE("FFT_SIZE_LOG2", LOG2($spp))</action>
</arg>
<arg>
<name>shift</name>
<type>string</type>
<value>normal</value>
<check>EQUAL($shift, "normal") OR EQUAL($shift, "reverse") OR EQUAL($shift, "natural")</check>
<check_message>FFT direction must be either "normal", "reverse", or "natural".</check_message>
<action>
IF(EQUAL($shift, "normal"), SR_WRITE("FFT_SHIFT_CONFIG", 0)) OR
IF(EQUAL($shift, "reverse"), SR_WRITE("FFT_SHIFT_CONFIG", 1)) OR
IF(EQUAL($shift, "natural"), SR_WRITE("FFT_SHIFT_CONFIG", 2))
</action>
</arg>
<arg>
<name>direction</name>
<type>string</type>
<value>forward</value>
<check>EQUAL($direction, "forward") OR EQUAL($direction, "reverse")</check>
<check_message>FFT direction must be either "forward" or "reverse".</check_message>
<action>
IF(EQUAL($direction, "forward"), SR_WRITE("FFT_DIRECTION", 1)) OR
IF(EQUAL($direction, "reverse"), SR_WRITE("FFT_DIRECTION", 0))
</action>
</arg>
<arg>
<name>scaling</name>
<type>int</type>
<!--scaling per radix-4 butterfly-->
<value>1706</value>
<action>SR_WRITE("FFT_SCALING", $scaling)</action>
</arg>
<arg>
<name>otype</name>
<type>string</type>
<value>sc16</value>
<check>EQUAL($otype, "sc16")</check>
<check_message>Output data type must be sc16.</check_message>
<!--TODO: Check against mag-out value (requires GET() function) -->
</arg>
<arg>
<name>reset</name>
<type>int</type>
<value>1</value>
<action>
IF(NOT(EQUAL($reset, 0)), SR_WRITE("FFT_RESET", 1) AND SR_WRITE("FFT_RESET", 0))
</action>
<!--TODO: Set to zero after setting, add publisher-->
</arg>
<arg>
<name>magnitude_out</name>
<type>string</type>
<value>COMPLEX</value>
<check>EQUAL($magnitude_out, "COMPLEX") OR EQUAL($magnitude_out, "MAGNITUDE") OR EQUAL($magnitude_out, "MAGNITUDE_SQUARED")</check>
<check_message>Output format must be one of: COMPLEX, MAGNITUDE, MAGNITUDE_SQUARED.</check_message>
<action>
IF(EQUAL($magnitude_out, "COMPLEX"), SR_WRITE("MAGNITUDE_OUT", 0)) OR
IF(EQUAL($magnitude_out, "MAGNITUDE"), SR_WRITE("MAGNITUDE_OUT", 1)) OR
IF(EQUAL($magnitude_out, "MAGNITUDE_SQUARED"), SR_WRITE("MAGNITUDE_OUT", 2))
</action>
<!--TODO: add publisher-->
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</sink>
<source>
<name>out</name>
<type>$otype</type> <!--TODO make this dependent on the output type -->
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</source>
</ports>
</nocblock>

View File

@ -1,36 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>FIFO</name>
<blockname>FIFO</blockname>
<!--Use default block controller-->
<key>Block</key>
<!--There can be several of these:-->
<ids>
<id revision="0">F1F00000</id>
</ids>
<ports>
<sink>
<name>in0</name>
</sink>
<source>
<name>out0</name>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,19 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>FIR Filter</name>
<blockname>FIR</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">F112</id>
</ids>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
</sink>
<source>
<name>out</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,201 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>fosphor</name>
<blockname>fosphor</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">666F</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>ENABLE</name>
<address>160</address>
</setreg>
<setreg>
<name>CLEAR</name>
<address>161</address>
</setreg>
<setreg>
<name>RANDOM</name>
<address>162</address>
</setreg>
<setreg>
<name>DECIM</name>
<address>168</address>
</setreg>
<setreg>
<name>OFFSET</name>
<address>170</address>
</setreg>
<setreg>
<name>SCALE</name>
<address>171</address>
</setreg>
<setreg>
<name>TRISE</name>
<address>172</address>
</setreg>
<setreg>
<name>TDECAY</name>
<address>173</address>
</setreg>
<setreg>
<name>ALPHA</name>
<address>174</address>
</setreg>
<setreg>
<name>EPSILON</name>
<address>175</address>
</setreg>
<setreg>
<name>WF_CTRL</name>
<address>176</address>
</setreg>
<setreg>
<name>WF_DECIM</name>
<address>177</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>1024</value>
</arg>
<arg>
<name>enable</name>
<type>int</type>
<value>3</value>
<check>GE($enable, 0) AND LE($enable, 3)</check>
<check_message>"fosphor enable value must be within [0, 3]"</check_message>
<action>SR_WRITE("ENABLE", $enable)</action>
</arg>
<arg>
<name>clear</name>
<type>int</type>
<action>IF(NOT(EQUAL($clear, 0)), SR_WRITE("CLEAR", $clear))</action>
</arg>
<arg>
<name>random</name>
<type>int</type>
<value>3</value>
<check>GE($random, 0) AND LE($random, 3)</check>
<check_message>"fosphor random mode value must be within [0, 3]"</check_message>
<action>SR_WRITE("RANDOM", $random)</action>
</arg>
<arg>
<name>decim</name>
<type>int</type>
<value>2</value>
<check>GE($decim, 2) AND LE($decim, 1024)</check>
<check_message>fosphor decim constant must be within [2, 1024]</check_message>
<action>SR_WRITE("DECIM", ADD($decim, -2))</action>
</arg>
<arg>
<name>offset</name>
<type>int</type>
<value>0</value>
<check>GE($offset, 0) AND LE($offset, 65536)</check>
<check_message>"fosphor offset value must be within [0, 65535]"</check_message>
<action>SR_WRITE("OFFSET", $offset)</action>
</arg>
<arg>
<name>scale</name>
<type>int</type>
<value>256</value>
<check>GE($scale, 0) AND LE($scale, 65536)</check>
<check_message>"fosphor scale value must be within [0, 65535]"</check_message>
<action>SR_WRITE("SCALE", $scale)</action>
</arg>
<arg>
<name>trise</name>
<type>int</type>
<value>4096</value>
<check>GE($trise, 0) AND LE($trise, 65536)</check>
<check_message>"fosphor trise value must be within [0, 65535]"</check_message>
<action>SR_WRITE("TRISE", $trise)</action>
</arg>
<arg>
<name>tdecay</name>
<type>int</type>
<value>16384</value>
<check>GE($tdecay, 0) AND LE($tdecay, 65536)</check>
<check_message>"fosphor tdecay value must be within [0, 65535]"</check_message>
<action>SR_WRITE("TDECAY", $tdecay)</action>
</arg>
<arg>
<name>alpha</name>
<type>int</type>
<value>65280</value>
<check>GE($alpha, 0) AND LE($alpha, 65536)</check>
<check_message>"fosphor alpha value must be within [0, 65535]"</check_message>
<action>SR_WRITE("ALPHA", $alpha)</action>
</arg>
<arg>
<name>epsilon</name>
<type>int</type>
<value>1</value>
<check>GE($epsilon, 0) AND LE($epsilon, 65536)</check>
<check_message>"fosphor epsilon value must be within [0, 65535]"</check_message>
<action>SR_WRITE("EPSILON", $epsilon)</action>
</arg>
<arg>
<name>wf_ctrl</name>
<type>int</type>
<value>0</value>
<check>GE($wf_ctrl, 0) AND LE($enable, 255)</check>
<check_message>"fosphor wf_ctrl value must be within [0, 255]"</check_message>
<action>SR_WRITE("WF_CTRL", $wf_ctrl)</action>
</arg>
<arg>
<name>wf_decim</name>
<type>int</type>
<value>8</value>
<check>GE($wf_decim, 2) AND LE($wf_decim, 256)</check>
<check_message>fosphor wf_decim constant must be within [2, 256]</check_message>
<action>SR_WRITE("WF_DECIM", ADD($wf_decim, -2))</action>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</sink>
<source>
<name>out_hist</name>
<type>u8</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
<port>0</port>
</source>
<source>
<name>out_wf</name>
<type>u8</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
<port>1</port>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,55 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Keep One in N</name>
<blockname>KeepOneInN</blockname>
<doc>
Block controller for the Keep One in N RFNoC block.
For every N packets received, this block will output a single packet.
- One input / output block port
- N up to 65535
</doc>
<!--There can be several of these:-->
<ids>
<id revision="0">0246</id>
</ids>
<registers>
<setreg>
<name>SR_N</name>
<address>129</address>
</setreg>
</registers>
<args>
<arg>
<name>n</name>
<type>int</type>
<value>256</value>
<action>SR_WRITE("SR_N", $n)</action>
</arg>
</args>
<ports>
<sink>
<name>in</name>
</sink>
<source>
<name>out</name>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,49 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Log Power</name>
<blockname>LogPwr</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">4C50</id>
</ids>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>256</value>
</arg>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</sink>
<source>
<name>out</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,50 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Moving Average</name>
<blockname>MovingAverage</blockname>
<ids>
<id revision="0">AAD2</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>SUM_LEN</name>
<address>192</address>
</setreg>
<setreg>
<name>DIVISOR</name>
<address>193</address>
</setreg>
<readback>
<name>RB_SUM_LEN</name>
<address>0</address>
</readback>
<readback>
<name>RB_DIVISOR</name>
<address>1</address>
</readback>
</registers>
<!-- Args -->
<args>
<arg>
<name>length</name>
<type>int</type>
<value>10</value>
<check>GE($length, 1) AND LE($length, 255)</check>
<check_message>Average length must be in [1, 255].</check_message>
<action>SR_WRITE("SUM_LEN", $length) AND SR_WRITE("DIVISOR", $length)</action>
</arg>
</args>
<!-- Ports -->
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<port>0</port>
</sink>
<source>
<name>avg</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,30 +0,0 @@
<nocblock>
<name>Null Source/Sink</name>
<blockname>NullSrcSink</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">0000000000000000</id>
</ids>
<!-- Args -->
<args>
<arg>
<name>line_rate</name>
<type>int</type>
<value>65535</value>
</arg>
<arg>
<name>bpp</name>
<type>int</type>
<value>256</value>
</arg>
</args>
<!-- Ports -->
<ports>
<sink>
<name>dump</name>
</sink>
<source>
<name>src</name>
</source>
</ports>
</nocblock>

View File

@ -1,31 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>OFDM Equalizer</name>
<blockname>OFDMEq</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">FF42</id>
</ids>
<!-- Args -->
<args>
<arg>
<name>fftsize</name>
<type>int</type>
<value>64</value>
</arg>
</args>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$fftsize</vlen>
<pkt_size>%vlen</pkt_size>
</sink>
<source>
<name>out</name>
<type>sc16</type>
<vlen>$fftsize</vlen>
<pkt_size>%vlen</pkt_size>
</source>
</ports>
</nocblock>

View File

@ -1,55 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Packet Resizer</name>
<blockname>PacketResizer</blockname>
<doc>
Block controller for the Packet Resizer RFNoC block.
The Packet Resizer RFNoC block changes the packet length of a stream. It can break large
packets into smaller packets or combine small packets into a single larger packet.
</doc>
<ids>
<id revision="0">12E5</id>
</ids>
<registers>
<setreg>
<name>SR_PKT_SIZE</name>
<address>129</address>
</setreg>
</registers>
<args>
<arg>
<name>pkt_size</name>
<type>int</type>
<value>32</value>
<check>GT($pkt_size, 0)</check>
<check_message>Packet size must be positive, non-zero.</check_message>
<action>SR_WRITE("SR_PKT_SIZE", $pkt_size)</action>
</arg>
</args>
<ports>
<sink>
<name>in</name>
</sink>
<source>
<name>out</name>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,59 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Radio (E31X)</name>
<blockname>Radio</blockname>
<key>E31XRadio</key>
<!--There can be several of these:-->
<ids>
<id revision="0">12AD100000003310</id>
</ids>
<!-- Registers -->
<registers>
<!--<setreg>-->
<!--<name>FFT_RESET</name>-->
<!--<address>131</address>-->
<!--</setreg>-->
<!--<readback>-->
<!--<name>RB_MAGNITUDE_OUT</name>-->
<!--<address>1</address>-->
<!--</readback>-->
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>508</value>
<!--<value>256</value>-->
<!--<check>GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)</check>-->
<!--<check_message>FFT size must be in [16, 4096] and a power of two.</check_message>-->
<!--<action>SR_WRITE("FFT_SIZE_LOG2", LOG2($spp)) AND SR_WRITE("AXIS_CONFIG_BUS", ADD(873472, LOG2($spp)))</action>-->
</arg>
</args>
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</sink>
<sink>
<name>in1</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</sink>
<source>
<name>out0</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</source>
<source>
<name>out1</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</source>
</ports>
</nocblock>

View File

@ -1,53 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Radio (Neon)</name>
<blockname>Radio</blockname>
<key>NeonRadio</key>
<!--There can be several of these:-->
<ids>
<id revision="0">12AD100000003320</id>
</ids>
<!-- Registers -->
<registers>
<!--<setreg>-->
<!--<name>FFT_RESET</name>-->
<!--<address>131</address>-->
<!--</setreg>-->
<!--<readback>-->
<!--<name>RB_MAGNITUDE_OUT</name>-->
<!--<address>1</address>-->
<!--</readback>-->
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>364</value>
</arg>
<arg>
<name>gain_mode</name>
<type>string</type>
<value>auto</value>
</arg>
</args>
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<sink>
<name>in1</name>
<type>sc16</type>
</sink>
<source>
<name>out1</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,267 +0,0 @@
<nocblock>
<name>Radio (EISCAT)</name>
<blockname>Radio</blockname>
<key>EISCATRadio</key>
<!--There can be several of these:-->
<ids>
<id revision="0">E15CA70000000000</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<!--1-Bit register. Enable Beam Stream Channels. There are 10, so this is a 10 bit value. -->
<name>SR_RX_STREAM_ENABLE</name>
<address>159</address>
</setreg>
<setreg>
<!--4-Bit register.
[0] Are we sending the upper or lower 5 beam contirbutions?
[1] = 1, beams_to_here goes directly to output (bypass neighbour contributions, single USRP)
[2] = 1, input to rx_receive direct from jesd_core (bypassing beamforming)
[3] = 1, if bypassing beamforming, instead output counter 00-FF
to output counter [3:0] = 0d10.
to output jesd streams directly [3:0] = 6 -->
<name>SR_BEAMS_TO_NEIGHBOR</name>
<address>202</address>
<value>14</value>
</setreg>
<setreg>
<!--1-Bit register. Are we expecting previous contributions? 1==yes we are -->
<name>SR_PREV_OR_NULL</name>
<address>203</address>
</setreg>
<setreg>
<name>SR_FIR_COMMANDS_RELOAD</name>
<address>198</address>
</setreg>
<setreg>
<name>SR_FIR_COMMANDS_CTRL_TIME_HI</name>
<address>199</address>
</setreg>
<setreg>
<name>SR_FIR_COMMANDS_CTRL_TIME_LO</name>
<address>200</address>
</setreg>
<setreg>
<!-- Use this to actually update taps in RAM -->
<name>SR_FIR_BRAM_WRITE_TAPS</name>
<address>201</address>
</setreg>
<setreg>
<name>SR_SYSREF</name>
<address>221</address>
</setreg>
<setreg>
<name>SR_CHANNEL_GAIN_0</name>
<address>204</address>
</setreg>
<readback>
<name>RB_NUM_TAPS</name>
<address>6</address>
</readback>
<readback>
<name>RB_NUM_CHANNELS</name>
<address>7</address>
</readback>
<readback>
<name>RB_NUM_BEAMS</name>
<address>8</address>
</readback>
<readback>
<name>RB_NUM_FILTERS</name>
<address>9</address>
</readback>
<readback>
<name>RB_STREAM_ENABLED</name>
<address>10</address>
</readback>
</registers>
<!-- Args -->
<args>
<!--Gets applied to all channels-->
<arg>
<name>spp</name>
<type>int</type>
<value>3968</value>
</arg>
<arg>
<name>taps</name>
<type>int</type>
</arg>
<arg>
<name>use_prev</name>
<type>int</type>
<value>0</value>
<check>EQUAL($use_prev, 0) OR EQUAL($use_prev, 1)</check>
<check_message>use_prev must be 0 or 1.</check_message>
<action>SR_WRITE("SR_PREV_OR_NULL", $use_prev)</action>
</arg>
<!--Direct access to the beams register-->
<arg>
<name>configure_beams</name>
<type>int</type>
</arg>
<!--Bit 0: 0: Upper 1: Lower Bit 1: 0: Use neighbours 1: no neighbours-->
<arg>
<name>choose_beams</name>
<type>int</type>
<value>2</value>
</arg>
<arg>
<name>enable_firs</name>
<type>int</type>
<value>1</value>
</arg>
<arg>
<name>enable_counter</name>
<type>int</type>
<value>0</value>
</arg>
<arg>
<name>channel_enable</name>
<type>int</type>
<value>1</value>
<action>SR_WRITE("SR_RX_STREAM_ENABLE", $channel_enable)</action>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<action>SR_WRITE("SR_CHANNEL_GAIN_0", 131071)</action>
<port>0</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>1</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>2</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>3</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>4</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>5</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>6</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>7</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>8</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>9</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>10</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>11</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>12</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>13</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>14</port>
</arg>
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<port>15</port>
</arg>
</args>
<ports>
<source>
<name>out0</name>
<type>s16</type>
</source>
<source>
<name>out1</name>
<type>s16</type>
</source>
<source>
<name>out2</name>
<type>s16</type>
</source>
<source>
<name>out3</name>
<type>s16</type>
</source>
<source>
<name>out4</name>
<type>s16</type>
</source>
<sink>
<name>in0</name>
<type>s16</type>
</sink>
<sink>
<name>in1</name>
<type>s16</type>
</sink>
<sink>
<name>in2</name>
<type>s16</type>
</sink>
<sink>
<name>in3</name>
<type>s16</type>
</sink>
<sink>
<name>in4</name>
<type>s16</type>
</sink>
</ports>
</nocblock>

View File

@ -1,53 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Radio (Magnesium)</name>
<blockname>Radio</blockname>
<key>MagnesiumRadio</key>
<!--There can be several of these:-->
<ids>
<id revision="0">12AD100000011312</id>
</ids>
<!-- Registers -->
<registers>
<!--<setreg>-->
<!--<name>FFT_RESET</name>-->
<!--<address>131</address>-->
<!--</setreg>-->
<!--<readback>-->
<!--<name>RB_MAGNITUDE_OUT</name>-->
<!--<address>1</address>-->
<!--</readback>-->
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>364</value>
</arg>
<arg>
<name>gain_mode</name>
<type>string</type>
<value>auto</value>
</arg>
</args>
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<sink>
<name>in1</name>
<type>sc16</type>
</sink>
<source>
<name>out1</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,47 +0,0 @@
<!--This defines the Radio (Rhodium) NoC-Block.-->
<nocblock>
<name>Radio (Rhodium)</name>
<blockname>Radio</blockname>
<key>RhodiumRadio</key>
<!--There can be several of these:-->
<ids>
<id revision="0">12AD100000000320</id>
</ids>
<!-- Registers -->
<registers>
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>364</value>
</arg>
<arg>
<name>spur_dodging</name>
<type>string</type>
<value>disabled</value>
</arg>
<arg>
<name>spur_dodging_threshold</name>
<type>double</type>
<value>2e6</value>
</arg>
<arg>
<name>highband_spur_reduction</name>
<type>string</type>
<value>disabled</value>
</arg>
</args>
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,55 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Radio (X300)</name>
<blockname>Radio</blockname>
<key>X300Radio</key>
<!--There can be several of these:-->
<ids>
<id revision="0">12AD100000000001</id>
</ids>
<!-- Registers -->
<registers>
<!--<setreg>-->
<!--<name>FFT_RESET</name>-->
<!--<address>131</address>-->
<!--</setreg>-->
<!--<readback>-->
<!--<name>RB_MAGNITUDE_OUT</name>-->
<!--<address>1</address>-->
<!--</readback>-->
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>364</value>
<!--<value>256</value>-->
<!--<check>GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)</check>-->
<!--<check_message>FFT size must be in [16, 4096] and a power of two.</check_message>-->
<!--<action>SR_WRITE("FFT_SIZE_LOG2", LOG2($spp)) AND SR_WRITE("AXIS_CONFIG_BUS", ADD(873472, LOG2($spp)))</action>-->
</arg>
</args>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</sink>
<source>
<name>out0</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</source>
<source>
<name>out1</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</source>
</ports>
</nocblock>

View File

@ -1,64 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Replay</name>
<blockname>Replay</blockname>
<key>Replay</key>
<!--There can be several of these:-->
<ids>
<id revision="0">4E91A00000000000</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>REC_BASE_ADDR</name>
<address>128</address>
</setreg>
<setreg>
<name>REC_BUFFER_SIZE</name>
<address>129</address>
</setreg>
<setreg>
<name>REC_RESTART</name>
<address>130</address>
</setreg>
<readback>
<name>REC_FULLNESS</name>
<address>131</address>
</readback>
<setreg>
<name>PLAY_BASE_ADDR</name>
<address>132</address>
</setreg>
<setreg>
<name>PLAY_BUFFER_SIZE</name>
<address>133</address>
</setreg>
<setreg>
<name>RX_CTRL_COMMAND</name>
<address>152</address>
</setreg>
<setreg>
<name>RX_CTRL_HALT</name>
<address>155</address>
</setreg>
<setreg>
<name>RX_CTRL_MAXLEN</name>
<address>156</address>
</setreg>
</registers>
<!-- Args -->
<args>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,72 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Replay</name>
<blockname>Replay</blockname>
<key>Replay</key>
<!--There can be several of these:-->
<ids>
<id revision="0">4E91A00000000002</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>REC_BASE_ADDR</name>
<address>128</address>
</setreg>
<setreg>
<name>REC_BUFFER_SIZE</name>
<address>129</address>
</setreg>
<setreg>
<name>REC_RESTART</name>
<address>130</address>
</setreg>
<readback>
<name>REC_FULLNESS</name>
<address>131</address>
</readback>
<setreg>
<name>PLAY_BASE_ADDR</name>
<address>132</address>
</setreg>
<setreg>
<name>PLAY_BUFFER_SIZE</name>
<address>133</address>
</setreg>
<setreg>
<name>RX_CTRL_COMMAND</name>
<address>152</address>
</setreg>
<setreg>
<name>RX_CTRL_HALT</name>
<address>155</address>
</setreg>
<setreg>
<name>RX_CTRL_MAXLEN</name>
<address>156</address>
</setreg>
</registers>
<!-- Args -->
<args>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<sink>
<name>in1</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<source>
<name>out1</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,87 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Replay</name>
<blockname>Replay</blockname>
<key>Replay</key>
<!--There can be several of these:-->
<ids>
<id revision="0">4E91A00000000004</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>REC_BASE_ADDR</name>
<address>128</address>
</setreg>
<setreg>
<name>REC_BUFFER_SIZE</name>
<address>129</address>
</setreg>
<setreg>
<name>REC_RESTART</name>
<address>130</address>
</setreg>
<readback>
<name>REC_FULLNESS</name>
<address>131</address>
</readback>
<setreg>
<name>PLAY_BASE_ADDR</name>
<address>132</address>
</setreg>
<setreg>
<name>PLAY_BUFFER_SIZE</name>
<address>133</address>
</setreg>
<setreg>
<name>RX_CTRL_COMMAND</name>
<address>152</address>
</setreg>
<setreg>
<name>RX_CTRL_HALT</name>
<address>155</address>
</setreg>
<setreg>
<name>RX_CTRL_MAXLEN</name>
<address>156</address>
</setreg>
</registers>
<!-- Args -->
<args>
</args>
<!--All the connections to the outside world are listed in 'ports':-->
<ports>
<sink>
<name>in0</name>
<type>sc16</type>
</sink>
<sink>
<name>in1</name>
<type>sc16</type>
</sink>
<sink>
<name>in2</name>
<type>sc16</type>
</sink>
<sink>
<name>in3</name>
<type>sc16</type>
</sink>
<source>
<name>out0</name>
<type>sc16</type>
</source>
<source>
<name>out1</name>
<type>sc16</type>
</source>
<source>
<name>out2</name>
<type>sc16</type>
</source>
<source>
<name>out3</name>
<type>sc16</type>
</source> </ports>
</nocblock>

View File

@ -1,101 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Schmidl &amp; Cox</name>
<blockname>SchmidlCox</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">5CC0</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>FRAME_LENGTH</name>
<address>129</address>
</setreg>
<setreg>
<name>CP_LENGTH</name>
<address>130</address>
</setreg>
<setreg>
<name>DELAY</name>
<address>131</address>
</setreg>
<setreg>
<name>NUM_SYMBOLS_MAX</name>
<address>132</address>
</setreg>
<setreg>
<name>THRESHOLD</name>
<address>134</address>
</setreg>
<setreg>
<name>AGC_REF_LEVEL</name>
<address>135</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>fftsize</name>
<type>int</type>
<value>64</value>
<!--TODO: Make publisher, when setting this value, check if equal to GET()-->
</arg>
<arg>
<name>frame_len</name>
<type>int</type>
<value>64</value>
<action>SR_WRITE("FRAME_LENGTH", $frame_len)</action>
</arg>
<arg>
<name>cp_len</name>
<type>int</type>
<value>16</value>
<action>SR_WRITE("CP_LENGTH", $cp_len)</action>
</arg>
<arg>
<name>threshold</name>
<type>double</type>
<value>0.8</value>
<check>GE($threshold, 0.0) AND LE($threshold, 1.0)</check>
<check_message>Detection threshold must be in [0, 1].</check_message>
<action>SR_WRITE("THRESHOLD", IROUND(MULT(16384.0, $threshold)))</action>
</arg>
<arg>
<name>delay</name>
<type>int</type>
<value>146</value>
<check>GE($delay, 0) AND LE($delay, 32767)</check>
<check_message>Invalid delay.</check_message>
<action>SR_WRITE("DELAY", $delay)</action>
</arg>
<arg>
<name>max_num_symbols</name>
<type>int</type>
<value>12</value>
<check>GE($max_num_symbols, 0) AND LE($max_num_symbols, 1000)</check>
<check_message>Invalid number of max symbols.</check_message>
<action>SR_WRITE("NUM_SYMBOLS_MAX", $max_num_symbols)</action>
</arg>
<arg>
<name>agc_ref_level</name>
<type>double</type>
<value>0.125</value>
<check>GE($agc_ref_level, 0.0) AND LE($agc_ref_level, 1.0)</check>
<check_message>AGC reference level must be in [0, 1].</check_message>
<action>SR_WRITE("AGC_REF_LEVEL", IROUND(MULT(32768.0, $agc_ref_level)))</action>
</arg>
</args>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
</sink>
<source>
<name>out</name>
<type>sc16</type>
<vlen>$fftsize</vlen>
<pkt_size>%vlen</pkt_size>
</source>
</ports>
</nocblock>

View File

@ -1,109 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>OFDM Constellation Demod</name>
<blockname>OFDMDemap</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">0FCD</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>MOD_ORDER</name>
<address>129</address>
</setreg>
<setreg>
<name>SCALING</name>
<address>130</address>
</setreg>
<setreg>
<name>OUTPUT_SYMBOLS</name>
<address>131</address>
</setreg>
<setreg>
<name>PKT_LEN</name>
<address>132</address>
</setreg>
<setreg>
<name>SET_EOB</name>
<address>133</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>fftsize</name>
<type>int</type>
<value>64</value>
</arg>
<arg>
<name>mod_order</name>
<type>int</type>
<value>4</value>
<check>GE($mod_order, 2) AND LE($mod_order, 64) AND IS_PWR_OF_2($mod_order)</check>
<check_message>Modulation order must be in (2, 4, 16, 64).</check_message>
<action>SR_WRITE("MOD_ORDER", LOG2($mod_order))</action>
</arg>
<arg>
<name>scaling</name>
<type>double</type>
<value>1.4142135623730951</value>
<check>GE($scaling, 0.1) AND LT($scaling, 4.0)</check>
<check_message>Invalid scaling.</check_message>
<action>SR_WRITE("SCALING", IROUND(MULT(16384.0, $scaling)))</action>
</arg>
<arg>
<name>output_symbols</name>
<type>int</type>
<value>1</value>
<check>EQUAL($output_symbols, 0) OR EQUAL($output_symbols, 1)</check>
<check_message>Output symbols can only be true (1) or false (0)</check_message>
<action>SR_WRITE("OUTPUT_SYMBOLS", $output_symbols)</action>
</arg>
<!-- Packet length in bytes -->
<arg>
<name>pkt_len</name>
<type>int</type>
<value>64</value>
<check>GE($pkt_len, 4) AND LE($pkt_len, 4096)</check>
<check_message>Packet length must be greater than or equal to 4 and less than or equal to 4096 bytes</check_message>
<action>SR_WRITE("PKT_LEN", $pkt_len)</action>
</arg>
<arg>
<name>set_eob</name>
<type>int</type>
<value>1</value>
<check>EQUAL($set_eob, 0) OR EQUAL($set_eob, 1)</check>
<check_message>Set end of burst can only be true (1) or false (0)</check_message>
<action>SR_WRITE("SET_EOB", $set_eob)</action>
</arg>
</args>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$fftsize</vlen>
</sink>
<source>
<name>out</name>
<type>u8</type>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,116 +0,0 @@
<nocblock>
<name>Signal Generator</name>
<blockname>SigGen</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">5166311000000000</id>
</ids>
<!-- Registers -->
<registers>
<!-- Reg 128 used for FREQ -->
<setreg>
<name>FREQ</name>
<address>129</address>
</setreg>
<setreg>
<name>CARTESIAN</name>
<address>130</address>
</setreg>
<setreg>
<name>ENABLE</name>
<address>132</address>
</setreg>
<setreg>
<name>CONSTANT</name>
<address>138</address>
</setreg>
<setreg>
<name>GAIN</name>
<address>139</address>
</setreg>
<setreg>
<name>PKT_SIZE</name>
<address>140</address>
</setreg>
<setreg>
<name>WAVEFORM</name>
<address>142</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>enable</name>
<type>int</type>
<value>0</value>
<check>EQUAL($enable, 0) OR EQUAL($enable, 1)</check>
<check_message>Enable is either 0 or 1.</check_message>
<action>SR_WRITE("ENABLE", $enable)</action>
</arg>
<arg>
<name>spp</name>
<type>int</type>
<value>256</value>
<action>SR_WRITE("PKT_SIZE", $spp)</action>
</arg>
<!-- Overall Gain -->
<arg>
<name>gain</name>
<type>double</type>
<value>1.0</value>
<check>GE($gain, 0.0) AND LE($gain, 1.0)</check>
<check_message>Invalid gain.</check_message>
<action>
SR_WRITE("GAIN", IROUND(MULT(32767.0,$gain)))
</action>
</arg>
<!-- Sine Wave, Constant I / Q -->
<arg>
<name>amplitude_i</name>
<type>double</type>
<value>1.0</value>
<check>GE($amplitude_i, -1.0) AND LE($amplitude_i, 1.0)</check>
<check_message>Invalid amplitude.</check_message>
</arg>
<arg>
<name>amplitude_q</name>
<type>double</type>
<value>1.0</value>
<check>GE($amplitude_q, -1.0) AND LE($amplitude_q, 1.0)</check>
<check_message>Invalid amplitude.</check_message>
<action>
SR_WRITE("CONSTANT", ADD(MULT(65536,IROUND(MULT(32767.0, $amplitude_i))),IROUND(MULT(32767.0, $amplitude_q))))
</action>
</arg>
<arg>
<name>frequency</name>
<type>double</type>
<value>0.1</value>
<check>GE($frequency, -1.0) AND LE($frequency, 1.0)</check>
<check_message>Invalid frequency.</check_message>
<action>SR_WRITE("FREQ", IROUND(MULT(-8192.0, $frequency)))</action>
</arg>
<arg>
<name>waveform</name>
<type>string</type>
<value>CONSTANT</value>
<check>EQUAL($waveform, "CONSTANT") OR EQUAL($waveform, "SINE_WAVE") OR EQUAL($waveform, "NOISE")</check>
<check_message>Waveform type should be one of: CONSTANT, SINE WAVE, NOISE.</check_message>
<action>
IF(EQUAL($waveform, "CONSTANT"), SR_WRITE("WAVEFORM", 0) AND SR_WRITE("CONSTANT", ADD(MULT(65536,IROUND(MULT(32767.0, $amplitude_i))),IROUND(MULT(32767.0, $amplitude_q))))) OR
IF(EQUAL($waveform, "SINE_WAVE"), SR_WRITE("WAVEFORM", 1) AND SR_WRITE("CARTESIAN", MULT(65536,28000))) OR
IF(EQUAL($waveform, "NOISE"), SR_WRITE("WAVEFORM", 2))
</action>
</arg>
</args>
<!-- Ports -->
<ports>
<sink>
<name>dump</name>
</sink>
<source>
<name>src</name>
<type>sc16</type>
</source>
</ports>
</nocblock>

View File

@ -1,38 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Split Stream</name>
<blockname>SplitStream</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">5757</id>
</ids>
<!-- This block takes any type, hence we skip the <type> tag: -->
<ports>
<sink>
<name>in</name>
</sink>
<source>
<name>out0</name>
</source>
<source>
<name>out1</name>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,84 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Vector IIR</name>
<blockname>VectorIIR</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">1112</id>
</ids>
<!-- Registers -->
<registers>
<setreg>
<name>VECTOR_LEN</name>
<address>129</address>
</setreg>
<setreg>
<name>ALPHA</name>
<address>130</address>
</setreg>
<setreg>
<name>BETA</name>
<address>131</address>
</setreg>
</registers>
<!-- Args -->
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>256</value>
<check>GE($spp, 1) AND LE($spp, 4096)</check>
<check_message>Vector length must be in [1, 4096].</check_message>
<action>SR_WRITE("VECTOR_LEN", $spp)</action>
</arg>
<arg>
<name>alpha</name>
<type>double</type>
<value>0.9</value>
<check>GT($alpha, 0.0) AND LT($alpha, 1.0)</check>
<check_message>Alpha must be in (0.0, 1.0).</check_message>
<!--We set the register value to alpha * 2^31 (Q1.31 format)-->
<action>SR_WRITE("ALPHA", IROUND(MULT($alpha, 2147483648.0)))</action>
</arg>
<arg>
<name>beta</name>
<type>double</type>
<value>0.1</value>
<check>GT($beta, 0.0) AND LT($beta, 1.0)</check>
<check_message>Beta must be in (0.0, 1.0).</check_message>
<!--We set the register value to alpha * 2^31 (Q1.31 format)-->
<action>SR_WRITE("BETA", IROUND(MULT($beta, 2147483648.0)))</action>
</arg>
</args>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</sink>
<source>
<name>out</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -1,47 +0,0 @@
<!--This defines one NoC-Block.-->
<nocblock>
<name>Window</name>
<blockname>Window</blockname>
<!--There can be several of these:-->
<ids>
<id revision="0">D053</id>
</ids>
<args>
<arg>
<name>spp</name>
<type>int</type>
<value>256</value>
</arg>
</args>
<ports>
<sink>
<name>in</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</sink>
<source>
<name>out</name>
<type>sc16</type>
<vlen>$spp</vlen>
<pkt_size>%vlen</pkt_size>
</source>
</ports>
<!--<components>-->
<!--<component>-->
<!--<key revision="1">nocshell</key>-->
<!--</component>-->
<!--<component srbase="0">-->
<!--[>Will look for a component with this key:<]-->
<!--<key revision="1">componentname</key>-->
<!--</component>-->
<!--</components>-->
<!--<connection>-->
<!--<source port="0">nocshell</source>-->
<!--<sink port="0">componentname</sink>-->
<!--</connection>-->
<!--<connection>-->
<!--<source port="0">componentname</source>-->
<!--<sink port="0">nocshell</sink>-->
<!--</connection>-->
</nocblock>

View File

@ -16,13 +16,6 @@
namespace uhd { namespace rfnoc {
// All these configure the XML reader
//! Where the RFNoC block/component definition files lie, relative to UHD_PKG_DIR
static const std::string XML_DEFAULT_PATH = "share/uhd/rfnoc";
//! The name of the environment variable storing the bath to the block definition files
static const std::string XML_PATH_ENV = "UHD_RFNOC_DIR";
static const uint64_t DEFAULT_NOC_ID_64 = 0xFFFFFFFFFFFFFFFF;
static const size_t NOC_SHELL_COMPAT_MAJOR = 5;
static const size_t NOC_SHELL_COMPAT_MINOR = 1;

View File

@ -1,14 +1,15 @@
#
# Copyright 2019 Ettus Research, a National Instruments Company
# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
file(GLOB yml_files "*.yml")
file(GLOB json_files "*.json")
# We always need this, even when RFNoC is 'disabled'
UHD_INSTALL(
FILES ${yml_files}
DESTINATION ${PKG_DATA_DIR}/erfnoc/blocks
FILES ${yml_files} ${json_files}
DESTINATION ${PKG_DATA_DIR}/rfnoc/core
COMPONENT headers # TODO: Different component
)
)

View File

@ -1,38 +0,0 @@
//
// Copyright 2016 Ettus Research
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP
#include <uhd/rfnoc/rate_node_ctrl.hpp>
#include <uhd/rfnoc/scalar_node_ctrl.hpp>
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief DDC block controller
*
* This block provides DSP for Rx operations.
* Its main component is a DDC chain, which can decimate over a wide range
* of decimation rates (using a CIC and halfband filters).
*
* It also includes a CORDIC component to shift signals in frequency.
*/
class UHD_RFNOC_API ddc_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base,
public rate_node_ctrl,
public scalar_node_ctrl
{
public:
UHD_RFNOC_BLOCK_OBJECT(ddc_block_ctrl)
}; /* class ddc_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP */

View File

@ -1,46 +0,0 @@
//
// Copyright 2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP
#define INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Block controller for a DMA FIFO block.
*
* The DMA FIFO block has the following features:
* - One input- and output-port (type agnostic)
* - Configurable base address and FIFO depth
* - The base storage for the FIFO can be device
* specific. Usually it will be an off-chip SDRAM
* bank.
*
*/
class UHD_RFNOC_API dma_fifo_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base
{
public:
UHD_RFNOC_BLOCK_OBJECT(dma_fifo_block_ctrl)
//! Configure the base address and depth of the FIFO (in bytes).
virtual void resize(
const uint32_t base_addr, const uint32_t depth, const size_t chan) = 0;
//! Returns the base address of the FIFO (in bytes).
uint32_t get_base_addr(const size_t chan) const;
//! Returns the depth of the FIFO (in bytes).
uint32_t get_depth(const size_t chan) const;
}; /* class dma_fifo_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP */

View File

@ -1,38 +0,0 @@
//
// Copyright 2016 Ettus Research
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP
#include <uhd/rfnoc/rate_node_ctrl.hpp>
#include <uhd/rfnoc/scalar_node_ctrl.hpp>
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief DUC block controller
*
* This block provides DSP for Tx operations.
* Its main component is a DUC chain, which can interpolate over a wide range
* of interpolation rates (using a CIC and halfband filters).
*
* It also includes a CORDIC component to shift signals in frequency.
*/
class UHD_RFNOC_API duc_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base,
public rate_node_ctrl,
public scalar_node_ctrl
{
public:
UHD_RFNOC_BLOCK_OBJECT(duc_block_ctrl)
}; /* class duc_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP */

View File

@ -1,45 +0,0 @@
//
// Copyright 2014-2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP
#define INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Block controller for the standard FIR RFNoC block.
*
* The standard FIR has the following features:
* - One input- and output-port
* - Configurable taps, but fixed number of taps
* - Supports data type sc16 (16-Bit fix-point complex samples)
*
* This block requires packets to be the same size as the FFT length.
* It will perform one FFT operation per incoming packet, treating it
* as a vector of samples.
*/
class UHD_RFNOC_API fir_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base
{
public:
UHD_RFNOC_BLOCK_OBJECT(fir_block_ctrl)
//! Configure the filter taps.
//
// The length of \p taps must correspond the number of taps
// in this block. If it's shorter, zeros will be padded.
// If it's longer, throws a uhd::value_error.
virtual void set_taps(const std::vector<int>& taps) = 0;
//! Returns the number of filter taps in this block.
virtual size_t get_n_taps() const = 0;
}; /* class fir_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP */

View File

@ -1,76 +0,0 @@
//
// Copyright 2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_HPP
#define INCLUDED_LIBUHD_RFNOC_GRAPH_HPP
#include <uhd/rfnoc/block_id.hpp>
#include <uhd/types/sid.hpp>
#include <uhd/utils/noncopyable.hpp>
namespace uhd { namespace rfnoc {
class graph : uhd::noncopyable
{
public:
typedef boost::shared_ptr<uhd::rfnoc::graph> sptr;
/*! Connect a RFNOC block with block ID \p src_block to another with block ID \p
* dst_block.
*
* This will:
* - Check if this connection is valid (IO signatures, see if types match)
* - Configure the flow control for the blocks
* - Configure SID for the upstream block
* - Register the upstream block in the downstream block
*/
virtual void connect(const block_id_t& src_block,
size_t src_block_port,
const block_id_t& dst_block,
size_t dst_block_port,
const size_t pkt_size = 0) = 0;
/*! Shorthand for connect().
*
* Using default ports for both source and destination.
*/
virtual void connect(const block_id_t& src_block, const block_id_t& dst_block) = 0;
/*! Anonymous connection.
*
* Danger, danger. You use this, you know what you're doing.
*
* \param src_block Source block ID
* \param src_block_port Source block port
* \param dst_sid SID to route traffic to
* \param buf_size_dst_bytes Destination window buffer in bytes
* \param pkt_size Hint what the packet size over this link will be
*/
virtual void connect_src(const block_id_t& src_block,
const size_t src_block_port,
const uhd::sid_t dst_sid,
const size_t buf_size_dst_bytes,
const size_t pkt_size) = 0;
/*! Anonymous connection
*
* Danger, danger. You use this, you know what you're doing.
*
* \param sink_block Sink block ID
* \param dst_block_port Destination (sink) block port
* \param bytes_per_ack Flow control frequency in bytes
*/
virtual void connect_sink(const block_id_t& sink_block,
const size_t dst_block_port,
const size_t bytes_per_ack) = 0;
virtual std::string get_name() const = 0;
};
}}; // namespace uhd::rfnoc
#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_HPP */

View File

@ -1,309 +0,0 @@
//
// Copyright 2014-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/constants.hpp>
#include <uhd/types/device_addr.hpp>
#include <uhd/utils/log.hpp>
#include <uhd/utils/noncopyable.hpp>
#include <stdint.h>
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <map>
#include <set>
namespace uhd { namespace usrp {
// Forward declaration for friend clause
class device3_impl;
}} // namespace uhd::usrp
namespace uhd { namespace rfnoc {
#define UHD_RFNOC_BLOCK_TRACE() UHD_LOGGER_TRACE("RFNOC")
/*! \brief Abstract base class for streaming nodes.
*
*/
class UHD_RFNOC_API node_ctrl_base;
class node_ctrl_base : uhd::noncopyable,
public boost::enable_shared_from_this<node_ctrl_base>
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<node_ctrl_base> sptr;
typedef boost::weak_ptr<node_ctrl_base> wptr;
typedef std::map<size_t, wptr> node_map_t;
typedef std::pair<size_t, wptr> node_map_pair_t;
typedef boost::function<void(void)> graph_update_cb_t;
/***********************************************************************
* Node control
**********************************************************************/
//! Returns a unique string that identifies this block.
virtual std::string unique_id() const;
/***********************************************************************
* Connections
**********************************************************************/
/*! Clears the list of connected nodes.
*/
virtual void clear();
node_map_t list_downstream_nodes()
{
return _downstream_nodes;
};
node_map_t list_upstream_nodes()
{
return _upstream_nodes;
};
/*! Disconnect this node from all neighbouring nodes.
*/
void disconnect();
/*! Identify \p output_port as unconnected
*/
void disconnect_output_port(const size_t output_port);
/*! Identify \p input_port as unconnected
*/
void disconnect_input_port(const size_t input_port);
// TODO we need a more atomic connect procedure, this is too error-prone.
/*! For an existing connection, store the remote port number.
*
* \throws uhd::value_error if \p this_port is not connected.
*/
void set_downstream_port(const size_t this_port, const size_t remote_port);
/*! Return the remote port of a connection on a given port.
*
* \throws uhd::value_error if \p this_port is not connected.
*/
size_t get_downstream_port(const size_t this_port);
/*! For an existing connection, store the remote port number.
*
* \throws uhd::value_error if \p this_port is not connected.
*/
void set_upstream_port(const size_t this_port, const size_t remote_port);
/*! Return the remote port of a connection on a given port.
*
* \throws uhd::value_error if \p this_port is not connected.
*/
size_t get_upstream_port(const size_t this_port);
/*! Find nodes downstream that match a predicate.
*
* Uses a non-recursive breadth-first search algorithm.
* On every branch, the search stops if a block matches.
* See this example:
* <pre>
* A -> B -> C -> C
* </pre>
* Say node A searches for nodes of type C. It will only find the
* first 'C' block, not the second.
*
* Returns blocks that are of type T.
*
* Search only goes downstream.
*/
template <typename T>
UHD_INLINE std::vector<boost::shared_ptr<T> > find_downstream_node(
bool active_only = false)
{
return _find_child_node<T, true>(active_only);
}
/*! Same as find_downstream_node(), but only search upstream.
*/
template <typename T>
UHD_INLINE std::vector<boost::shared_ptr<T> > find_upstream_node(
bool active_only = false)
{
return _find_child_node<T, false>(active_only);
}
/*! Checks if downstream nodes share a common, unique property.
*
* This will use find_downstream_node() to find all nodes downstream of
* this that are of type T. Then it will use \p get_property to return a
* property from all of them. If all these properties are identical, it will
* return that property. Otherwise, it will throw a uhd::runtime_error.
*
* \p get_property A functor to return the property from a node
* \p null_value If \p get_property returns this value, that node is skipped.
* \p explored_nodes A list of nodes to exclude from the search. This is typically
* to avoid recursion loops.
*/
template <typename T, typename value_type>
UHD_INLINE value_type find_downstream_unique_property(
boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property,
value_type null_value,
const std::set<boost::shared_ptr<T> >& exclude_nodes =
std::set<boost::shared_ptr<T> >())
{
return _find_unique_property<T, value_type, true>(
get_property, null_value, exclude_nodes);
}
/*! Like find_downstream_unique_property(), but searches upstream.
*/
template <typename T, typename value_type>
UHD_INLINE value_type find_upstream_unique_property(
boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property,
value_type null_value,
const std::set<boost::shared_ptr<T> >& exclude_nodes =
std::set<boost::shared_ptr<T> >())
{
return _find_unique_property<T, value_type, false>(
get_property, null_value, exclude_nodes);
}
protected:
/***********************************************************************
* Structors
**********************************************************************/
node_ctrl_base(void) : _num_input_ports(0), _num_output_ports(0) {}
virtual ~node_ctrl_base()
{
disconnect();
}
/***********************************************************************
* Protected members
**********************************************************************/
//! Stores default arguments
uhd::device_addr_t _args;
// TODO make these private
//! List of upstream nodes
node_map_t _upstream_nodes;
//! List of downstream nodes
node_map_t _downstream_nodes;
/*! Number of input ports
*/
size_t _num_input_ports;
/*! Number of output ports
*/
size_t _num_output_ports;
/*! For every output port, store rx streamer activity.
*
* If _rx_streamer_active[0] == true, this means that an active rx
* streamer is operating on port 0. If it is false, or if the entry
* does not exist, there is no streamer.
* Values are toggled by set_rx_streamer().
*/
std::map<size_t, bool> _rx_streamer_active;
/*! For every input port, store tx streamer activity.
*
* If _tx_streamer_active[0] == true, this means that an active tx
* streamer is operating on port 0. If it is false, or if the entry
* does not exist, there is no streamer.
* Values are toggled by set_tx_streamer().
*/
std::map<size_t, bool> _tx_streamer_active;
/***********************************************************************
* Connections
**********************************************************************/
/*! Registers another node as downstream of this node, connected to a given port.
*
* This implies that this node is a source node, and the downstream node is
* a sink node.
* See also uhd::rfnoc::source_node_ctrl::_register_downstream_node().
*/
virtual void _register_downstream_node(
node_ctrl_base::sptr downstream_node, size_t port);
/*! Registers another node as upstream of this node, connected to a given port.
*
* This implies that this node is a sink node, and the upstream node is
* a source node.
* See also uhd::rfnoc::sink_node_ctrl::_register_upstream_node().
*/
virtual void _register_upstream_node(node_ctrl_base::sptr upstream_node, size_t port);
/*! Initiate the update graph callback
*
* Call this from your block when you've changed one of these:
* - sampling rate
* - scaling
* - tick rate
*/
void update_graph()
{
_graph_update_cb();
}
private:
friend class uhd::usrp::device3_impl;
/*! Implements the search algorithm for find_downstream_node() and
* find_upstream_node().
*
* Depending on \p downstream, "child nodes" are either defined as
* nodes connected downstream or upstream.
*
* \param downstream Set to true if search goes downstream, false for upstream.
*/
template <typename T, bool downstream>
std::vector<boost::shared_ptr<T> > _find_child_node(bool active_only = false);
/*! Implements the search algorithm for find_downstream_unique_property() and
* find_upstream_unique_property().
*
* Depending on \p downstream, "child nodes" are either defined as
* nodes connected downstream or upstream.
*
* \param downstream Set to true if search goes downstream, false for upstream.
*/
template <typename T, typename value_type, bool downstream>
value_type _find_unique_property(
boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property,
value_type NULL_VALUE,
const std::set<boost::shared_ptr<T> >& exclude_nodes);
void set_graph_update_cb(graph_update_cb_t graph_update_cb)
{
_graph_update_cb = graph_update_cb;
}
/*! Stores the remote port number of a downstream connection.
*/
std::map<size_t, size_t> _upstream_ports;
/*! Stores the remote port number of a downstream connection.
*/
std::map<size_t, size_t> _downstream_ports;
graph_update_cb_t _graph_update_cb;
}; /* class node_ctrl_base */
}} /* namespace uhd::rfnoc */
#include <uhd/rfnoc/node_ctrl_base.ipp>
#endif /* INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP */

View File

@ -1,156 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
// Implements templated functions from node_ctrl_base.hpp
#ifndef INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP
#define INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP
#include <uhd/exception.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
namespace uhd {
namespace rfnoc {
template <typename T, bool downstream>
std::vector< boost::shared_ptr<T> > node_ctrl_base::_find_child_node(bool active_only)
{
typedef boost::shared_ptr<T> T_sptr;
static const size_t MAX_ITER = 20;
size_t iters = 0;
// List of return values:
std::set< T_sptr > results_s;
// To avoid cycles:
std::set < sptr > explored;
// Initialize our search queue with ourself:
std::set < node_map_pair_t > search_q;
// FIXME: Port is initialized to ANY_PORT, but it should really be
// passed in by the caller.
search_q.insert(node_map_pair_t(ANY_PORT, shared_from_this()));
std::set < node_map_pair_t > next_q;
while (iters++ < MAX_ITER) {
next_q.clear();
BOOST_FOREACH(const node_map_pair_t node_pair, search_q) {
sptr node = node_pair.second.lock();
if (not node)
{
continue;
}
size_t our_port = node_pair.first;
// Add this node to the list of explored nodes
explored.insert(node);
// Create set of all child nodes of this_node that are not in explored:
std::set< node_map_pair_t > next_nodes;
{
node_map_t all_next_nodes = downstream ?
node->list_downstream_nodes() :
node->list_upstream_nodes();
for (
node_map_t::iterator it = all_next_nodes.begin();
it != all_next_nodes.end();
++it
) {
size_t connected_port = it->first;
// If port is given, limit traversal to only that port.
if (our_port != ANY_PORT and our_port != connected_port)
{
continue;
}
if (active_only
and not (downstream ?
_tx_streamer_active[connected_port] :
_rx_streamer_active[connected_port] )) {
continue;
}
sptr one_next_node = it->second.lock();
if (not one_next_node or explored.count(one_next_node)) {
continue;
}
T_sptr next_node_sptr = boost::dynamic_pointer_cast<T>(one_next_node);
if (next_node_sptr) {
results_s.insert(next_node_sptr);
} else {
size_t next_port = ANY_PORT;
// FIXME: Need proper mapping from input port
// to output port.
// The code below assumes that blocks with the same
// number of connected upstream and downstream nodes
// map each input port directly to the same output
// port. This limits the graph traversal to prevent
// finding nodes that are not part of this chain.
if (one_next_node->_num_input_ports
and (one_next_node->_num_input_ports ==
one_next_node->_num_output_ports))
{
next_port = (downstream ?
node->get_downstream_port(connected_port) :
node->get_upstream_port(connected_port));
}
next_nodes.insert(node_map_pair_t(next_port, it->second));
}
}
}
// Add all of these nodes to the next search queue
next_q.insert(next_nodes.begin(), next_nodes.end());
}
// If next_q is empty, we've exhausted our graph
if (next_q.empty()) {
break;
}
// Re-init the search queue
search_q = next_q;
}
std::vector< T_sptr > results(results_s.begin(), results_s.end());
return results;
}
template <typename T, typename value_type, bool downstream>
value_type node_ctrl_base::_find_unique_property(
boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property,
value_type NULL_VALUE,
const std::set< boost::shared_ptr<T> > &exclude_nodes
) {
std::vector< boost::shared_ptr<T> > descendant_rate_nodes = _find_child_node<T, downstream>();
value_type ret_val = NULL_VALUE;
std::string first_node_id;
BOOST_FOREACH(const boost::shared_ptr<T> &node, descendant_rate_nodes) {
if (exclude_nodes.count(node)) {
continue;
}
// FIXME we need to know the port!!!
size_t port = ANY_PORT; // NOOO! this is wrong!!!! FIXME
value_type this_property = get_property(node, port);
if (this_property == NULL_VALUE) {
continue;
}
// We use the first property we find as reference
if (ret_val == NULL_VALUE) {
ret_val = this_property;
first_node_id = node->unique_id();
continue;
}
// In all subsequent finds, we make sure the property is equal to the reference
if (this_property != ret_val) {
throw uhd::runtime_error(
str(
boost::format("Node %1% specifies %2%, node %3% specifies %4%")
% first_node_id % ret_val % node->unique_id() % this_property
)
);
}
}
return ret_val;
}
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP */
// vim: sw=4 et:

View File

@ -1,68 +0,0 @@
//
// Copyright 2014-2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Provide access to a 'null block'.
*
* A 'null block' is a specific block, which comes with a couple
* of features useful for testing:
* - It can produce data at a given line rate, with a configurable
* packet size.
* - It can be used to dump packets ("null sink", "bit bucket")
*
* This block also serves as an example of how to create your own
* C++ classes to control your block.
*
* As a true source, it understands the following stream commands:
* - STREAM_MODE_START_CONTINUOUS
* - STREAM_MODE_STOP_CONTINUOUS
*
* Other stream commands are not understood and issue_stream_cmd()
* will throw if it receives them.
*/
class null_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base
{
public:
// This macro must always be at the top of the public section in an RFNoC block class
UHD_RFNOC_BLOCK_OBJECT(null_block_ctrl)
//! Set this register to number of lines per packet
static const uint32_t SR_LINES_PER_PACKET = 129;
//! Set this register to number of cycles between producing a line
static const uint32_t SR_LINE_RATE = 130;
//! Set this register to non-zero to start producing data
static const uint32_t SR_ENABLE_STREAM = 131;
static const size_t DEFAULT_LINES_PER_PACKET = 32;
static const size_t BYTES_PER_LINE = 8;
//! Custom function to set the rate at which data is produced.
// Note: This is 'cycles per line', so the bit rate is actually
// 64 times this value (byte/s is 8*rate etc.)
//
// Equivalent to writing to line_rate/value in the property tree.
//
// \param The rate you want to set this to
// \param The clock rate of this block's clock domain
// \returns the actual line rate (will find closest possible).
virtual double set_line_rate(double rate, double clock_rate = 166.6e6) = 0;
//! Return the current line rate. Equivalent to reading line_rate/value
// from the property tree.
virtual double get_line_rate(double clock_rate = 166.6e6) const = 0;
}; /* class null_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP */

View File

@ -1,521 +0,0 @@
//
// Copyright 2015-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP
#include <uhd/rfnoc/rate_node_ctrl.hpp>
#include <uhd/rfnoc/scalar_node_ctrl.hpp>
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
#include <uhd/rfnoc/terminator_node_ctrl.hpp>
#include <uhd/rfnoc/tick_node_ctrl.hpp>
#include <uhd/types/direction.hpp>
#include <uhd/types/ranges.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Block controller for all RFNoC-based radio blocks
*/
class UHD_RFNOC_API radio_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base,
public rate_node_ctrl,
public tick_node_ctrl,
public terminator_node_ctrl
{
public:
UHD_RFNOC_BLOCK_OBJECT(radio_ctrl)
virtual ~radio_ctrl() {}
//! A wildcard channel index
static const size_t ALL_CHANS = size_t(~0);
//! A wildcard gain element name
static const std::string ALL_GAINS;
//! A wildcard local oscillator element name
static const std::string ALL_LOS;
/************************************************************************
* API calls
***********************************************************************/
/*! Return the tick rate on all channels (rx and tx).
*
* \return The tick rate.
*/
virtual double get_rate() const = 0;
/*! Set the tick/sample rate on all channels (rx and tx).
*
* Will coerce to the nearest possible rate and return the actual value.
*/
virtual double set_rate(double rate) = 0;
/*! Return the selected TX antenna for channel \p chan.
*
* \return The selected antenna.
*/
virtual std::string get_tx_antenna(const size_t chan) /* const */ = 0;
/*! Select RX antenna \p for channel \p chan.
*
* \throws uhd::value_error if \p ant is not a valid value.
*/
virtual void set_tx_antenna(const std::string& ant, const size_t chan) = 0;
/*! Return the selected RX antenna for channel \p chan.
*
* \return The selected antenna.
*/
virtual std::string get_rx_antenna(const size_t chan) /* const */ = 0;
/*! Select RX antenna \p for channel \p chan.
*
* \throws uhd::value_error if \p ant is not a valid value.
*/
virtual void set_rx_antenna(const std::string& ant, const size_t chan) = 0;
/*! Return the current transmit LO frequency on channel \p chan.
*
* Note that the AD9361 only has one LO for all TX channels, and the
* \p chan parameter is thus only for API compatibility.
*
* \return The current LO frequency.
*/
virtual double get_tx_frequency(const size_t chan) /* const */ = 0;
/*! Tune the TX LO for channel \p chan.
*
* This function will attempt to tune as close as possible, and return a
* coerced value of the actual tuning result.
*
* \param freq Frequency in Hz
* \param chan Channel to tune
*
* \return The actual LO frequency.
*/
virtual double set_tx_frequency(const double freq, size_t chan) = 0;
/*! Return the current receive LO frequency on channel \p chan.
*
* \return The current LO frequency.
*/
virtual double get_rx_frequency(const size_t chan) /* const */ = 0;
/*! Tune the RX LO for channel \p chan.
*
* This function will attempt to tune as close as possible, and return a
* coerced value of the actual tuning result.
*
* \param freq Requested LO frequency
* \param chan Channel number.
* \return The actual LO frequency.
*/
virtual double set_rx_frequency(const double freq, const size_t chan) = 0;
/*! Return the transmit gain on channel \p chan
*
* \return The actual gain value
*/
virtual double get_tx_gain(const size_t chan) = 0;
/*! Set the transmit gain on channel \p chan
*
* This function will attempt to set the gain as close as possible,
* and return a coerced value of the actual gain value.
*
* \return The actual gain value
*/
virtual double set_tx_gain(const double gain, const size_t chan) = 0;
/*! Return the transmit gain on channel \p chan
*
* \return The actual gain value
*/
virtual double get_rx_gain(const size_t chan) = 0;
/*! Set the transmit gain on channel \p chan
*
* This function will attempt to set the gain as close as possible,
* and return a coerced value of the actual gain value.
*
* \return The actual gain value
*/
virtual double set_rx_gain(const double gain, const size_t chan) = 0;
/*! Return the analog filter bandwidth channel \p chan
*
* \return The actual bandwidth value
*/
virtual double get_tx_bandwidth(const size_t chan) = 0;
/*! Set the analog filter bandwidth channel \p chan
*
* This function will attempt to set the analog bandwidth.
*
* \return The actual bandwidth value
*/
virtual double set_tx_bandwidth(const double bandwidth, const size_t chan) = 0;
/*! Return the analog filter bandwidth channel \p chan
*
* \return The actual bandwidth value
*/
virtual double get_rx_bandwidth(const size_t chan) = 0;
/*! Set the analog filter bandwidth channel \p chan
*
* This function will attempt to set the analog bandwidth.
*
* \return The actual bandwidth value
*/
virtual double set_rx_bandwidth(const double bandwidth, const size_t chan) = 0;
/*! Sets the time in the radio's timekeeper to the given value.
*
* Note that there is a non-deterministic delay between calling this
* function and the valung written to the register. For setting the
* time in alignment with a certain reference time, use
* set_time_next_pps().
*/
virtual void set_time_now(const time_spec_t& time_spec) = 0;
/*! Set the time registers at the next pps tick.
*
* The values will not be latched in until the pulse occurs.
* It is recommended that the user sleep(1) after calling to ensure
* that the time registers will be in a known state prior to use.
*
* Note: Because this call sets the time on the "next" pps,
* the seconds in the time spec should be current seconds + 1.
*
* \param time_spec the time to latch into the timekeeper
*/
virtual void set_time_next_pps(const time_spec_t& time_spec) = 0;
/*! Get the current time in the timekeeper registers.
*
* Note that there is a non-deterministic delay between the time the
* register is read and the time the function value is returned.
* To get the time with respect to a tick edge, use get_time_last_pps().
*
* \return A timespec representing current radio time
*/
virtual time_spec_t get_time_now() = 0;
/*! Get the time when the last PPS pulse occurred.
*
* \return A timespec representing the last PPS
*/
virtual time_spec_t get_time_last_pps() = 0;
/*! Returns the list of GPIO banks that are associated with this radio.
*
* \returns list of GPIO bank names
*/
virtual std::vector<std::string> get_gpio_banks() const = 0;
/*!
* Set a GPIO attribute on a particular GPIO bank.
* Possible attribute names:
* - CTRL - 1 for ATR mode 0 for GPIO mode
* - DDR - 1 for output 0 for input
* - OUT - GPIO output level (not ATR mode)
* - ATR_0X - ATR idle state
* - ATR_RX - ATR receive only state
* - ATR_TX - ATR transmit only state
* - ATR_XX - ATR full duplex state
* \param bank the name of a GPIO bank (e.g., FP0)
* \param attr the name of a GPIO attribute (e.g., CTRL)
* \param value the new value for this GPIO bank
* \param mask the bit mask to effect which pins are changed
*/
virtual void set_gpio_attr(const std::string& bank,
const std::string& attr,
const uint32_t value,
const uint32_t mask) = 0;
/*!
* Get a GPIO attribute on a particular GPIO bank.
* Possible attribute names:
* - CTRL - 1 for ATR mode 0 for GPIO mode
* - DDR - 1 for output 0 for input
* - OUT - GPIO output level (not ATR mode)
* - ATR_0X - ATR idle state
* - ATR_RX - ATR receive only state
* - ATR_TX - ATR transmit only state
* - ATR_XX - ATR full duplex state
* - READBACK - readback input GPIOs
* \param bank the name of a GPIO bank
* \param attr the name of a GPIO attribute
* \return the value set for this attribute
*/
virtual uint32_t get_gpio_attr(const std::string& bank, const std::string& attr) = 0;
/**************************************************************************
* LO Controls
*************************************************************************/
/*! Get a list of possible LO stage names
*
* \param chan the channel index 0 to N-1
* \return a vector of strings for possible LO names
*/
virtual std::vector<std::string> get_rx_lo_names(const size_t chan) = 0;
/*! Get a list of possible LO sources.
*
* Channels which do not have controllable LO sources
* will return "internal".
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return a vector of strings for possible settings
*/
virtual std::vector<std::string> get_rx_lo_sources(
const std::string& name, const size_t chan) = 0;
/*!
* Get the LO frequency range of the RX LO.
* If the channel does not have independently configurable LOs
* the rf frequency range will be returned.
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return a frequency range object
*/
virtual freq_range_t get_rx_lo_freq_range(
const std::string& name, const size_t chan) = 0;
/*!
* Set the LO source for a channel.
* For usrps that support selectable LOs, this function
* allows switching between them.
* Typical options for source: internal, external.
* \param src a string representing the LO source
* \param name the name of the LO stage to update
* \param chan the channel index 0 to N-1
*/
virtual void set_rx_lo_source(
const std::string& src, const std::string& name, const size_t chan) = 0;
/*!
* Get the currently set LO source.
* Channels without controllable LO sources will return
* "internal"
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return the configured LO source
*/
virtual const std::string get_rx_lo_source(
const std::string& name, const size_t chan) = 0;
/*!
* Set whether the LO used by the usrp device is exported
* For usrps that support exportable LOs, this function
* configures if the LO used by chan is exported or not.
* \param enabled if true then export the LO
* \param name the name of the LO stage to update
* \param chan the channel index 0 to N-1 for the source channel
*/
virtual void set_rx_lo_export_enabled(
bool enabled, const std::string& name, const size_t chan) = 0;
/*!
* Returns true if the currently selected LO is being exported.
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
*/
virtual bool get_rx_lo_export_enabled(const std::string& name, const size_t chan) = 0;
/*!
* Set the RX LO frequency (Advanced).
* \param freq the frequency to set the LO to
* \param name the name of the LO stage to update
* \param chan the channel index 0 to N-1
* \return a coerced LO frequency
*/
virtual double set_rx_lo_freq(
double freq, const std::string& name, const size_t chan) = 0;
/*!
* Get the current RX LO frequency (Advanced).
* If the channel does not have independently configurable LOs
* the current rf frequency will be returned.
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return the configured LO frequency
*/
virtual double get_rx_lo_freq(const std::string& name, const size_t chan) = 0;
/*! Get a list of possible LO stage names
*
* \param chan the channel index 0 to N-1
* \return a vector of strings for possible LO names
*/
virtual std::vector<std::string> get_tx_lo_names(const size_t chan) = 0;
/*! Get a list of possible LO sources.
*
* Channels which do not have controllable LO sources
* will return "internal".
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return a vector of strings for possible settings
*/
virtual std::vector<std::string> get_tx_lo_sources(
const std::string& name, const size_t chan) = 0;
/*!
* Get the LO frequency range of the tx LO.
* If the channel does not have independently configurable LOs
* the rf frequency range will be returned.
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return a frequency range object
*/
virtual freq_range_t get_tx_lo_freq_range(
const std::string& name, const size_t chan) = 0;
/*!
* Set the LO source for a channel.
* For usrps that support selectable LOs, this function
* allows switching between them.
* Typical options for source: internal, external.
* \param src a string representing the LO source
* \param name the name of the LO stage to update
* \param chan the channel index 0 to N-1
*/
virtual void set_tx_lo_source(
const std::string& src, const std::string& name, const size_t chan) = 0;
/*!
* Get the currently set LO source.
* Channels without controllable LO sources will return
* "internal"
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return the configured LO source
*/
virtual const std::string get_tx_lo_source(
const std::string& name, const size_t chan) = 0;
/*!
* Set whether the LO used by the usrp device is exported
* For usrps that support exportable LOs, this function
* configures if the LO used by chan is exported or not.
* \param enabled if true then export the LO
* \param name the name of the LO stage to update
* \param chan the channel index 0 to N-1 for the source channel
*/
virtual void set_tx_lo_export_enabled(
const bool enabled, const std::string& name, const size_t chan) = 0;
/*!
* Returns true if the currently selected LO is being exported.
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
*/
virtual bool get_tx_lo_export_enabled(const std::string& name, const size_t chan) = 0;
/*! Set the tx LO frequency (Advanced).
*
* See also multi_usrp::set_tx_lo_freq().
*
* \param freq the frequency to set the LO to
* \param name the name of the LO stage to update
* \param chan the channel index 0 to N-1
* \return a coerced LO frequency
*/
virtual double set_tx_lo_freq(
const double freq, const std::string& name, const size_t chan) = 0;
/*! Get the current TX LO frequency (Advanced).
*
* See also multi_usrp::get_tx_lo_freq()
*
* If the channel does not have independently configurable LOs
* the current RF frequency will be returned.
*
* \param name the name of the LO stage to query
* \param chan the channel index 0 to N-1
* \return the configured LO frequency
*/
virtual double get_tx_lo_freq(const std::string& name, const size_t chan) = 0;
/**************************************************************************
* Time and clock control
*************************************************************************/
/*!
* Set the time source for this radio.
*
* May affect other radio blocks.
*
* \param source A string representing the time source
* \throws uhd::value_error if the value can't be applied
*/
virtual void set_time_source(const std::string& source) = 0;
/*!
* Get the currently set time source.
*
* \return the string representing the time source
*/
virtual std::string get_time_source() = 0;
/*!
* Get a list of possible time sources.
*
* \return a vector of strings for possible settings
*/
virtual std::vector<std::string> get_time_sources() = 0;
/*!
* Set the clock source for the usrp device (for reference clock).
*
* Typical options for source: internal, external.
*
* \param source a string representing the clock source
*/
virtual void set_clock_source(const std::string& source) = 0;
/*!
* Get the currently set clock source.
*
* \return the string representing the clock source
*/
virtual std::string get_clock_source() = 0;
/*!
* Get a list of possible clock sources.
*
* \return a vector of strings for possible settings
*/
virtual std::vector<std::string> get_clock_sources() = 0;
/*! Given a frontend name, return the channel mapping.
*
* E.g.: For a TwinRX board, there's two frontends, '0' and '1', which
* map to channels 0 and 1 respectively. A BasicRX boards has alphabetical
* frontends (A, B) which map to channels differently.
*/
virtual size_t get_chan_from_dboard_fe(
const std::string& fe, const uhd::direction_t dir) = 0;
/*! The inverse function to get_chan_from_dboard_fe()
*/
virtual std::string get_dboard_fe_from_chan(
const size_t chan, const uhd::direction_t dir) = 0;
/*! Enable or disable the setting of timestamps on Rx.
*/
virtual void enable_rx_timestamps(const bool enable, const size_t chan) = 0;
}; /* class radio_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP */

View File

@ -1,54 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/constants.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Sampling-rate-aware node control
*
* A "rate" node is a streaming node is a point in the flow graph
* that is aware of sampling rates. Such nodes include:
* - Radio Controls (these actually set a sampling rate)
* - Decimating FIR filters (their output rates depend on both
* incoming rates and their own settings, i.e. the decimation)
* - Streaming terminators (these need to know the sampling rates
* to configure the connected streamers)
*/
class UHD_RFNOC_API rate_node_ctrl;
class rate_node_ctrl : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<rate_node_ctrl> sptr;
//! This value is used by rate nodes that don't actually set a rate themselves
static const double RATE_UNDEFINED;
/***********************************************************************
* Rate controls
**********************************************************************/
/*! Returns the sampling rate this block expects at its input.
*
* A radio will simply return the sampling rate it is set to.
* A decimating FIR filter will ask downstream for the input sampling rate
* and then return that value multiplied by the decimation factor.
*
*/
virtual double get_input_samp_rate(size_t port = ANY_PORT);
virtual double get_output_samp_rate(size_t port = ANY_PORT);
}; /* class rate_node_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP */

View File

@ -1,72 +0,0 @@
//
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP
#define INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Replay block controller
*
* The replay block has the following features:
* - One input and one output
* - The ability to record and playback data
* - Configurable base addresses and buffer sizes
* - Independent record and playback controls
* - Radio-like playback interface
* - The storage for the replay data can be any
* memory, usually an off-chip DRAM.
*
*/
class UHD_RFNOC_API replay_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base
{
public:
UHD_RFNOC_BLOCK_OBJECT(replay_block_ctrl)
//! Configure the base address and size of the record buffer region (in bytes).
virtual void config_record(
const uint32_t base_addr, const uint32_t size, const size_t chan) = 0;
//! Configure the base address and size of the playback buffer region (in bytes).
virtual void config_play(
const uint32_t base_addr, const uint32_t size, const size_t chan) = 0;
//! Restarts recording at the beginning of the record buffer
virtual void record_restart(const size_t chan) = 0;
//! Returns the base address of the record buffer (in bytes).
virtual uint32_t get_record_addr(const size_t chan) = 0;
//! Returns the base address of the playback buffer (in bytes).
virtual uint32_t get_play_addr(const size_t chan) = 0;
//! Returns the size of the record buffer (in bytes).
virtual uint32_t get_record_size(const size_t chan) = 0;
//! Returns the current fullness of the record buffer (in bytes).
virtual uint32_t get_record_fullness(const size_t chan) = 0;
//! Returns the size of the playback buffer (in bytes).
virtual uint32_t get_play_size(const size_t chan) = 0;
//! Sets the size of the packets played by the Replay block (in 64-bit words)
virtual void set_words_per_packet(const uint32_t num_words, const size_t chan) = 0;
//! Returns the size of the packets played by the Replay block (in 64-bit words)
virtual uint32_t get_words_per_packet(const size_t chan) = 0;
//! Halts playback and clears the playback command FIFO
virtual void play_halt(const size_t chan) = 0;
}; /* class replay_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP */

View File

@ -1,62 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/constants.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Scaling node control
*
* A "scalar" node is a streaming node in which a scaling takes
* place, usually for the conversion between fixed point and floating
* point (the latter usually being normalized between -1 and 1).
*
* Such blocks include:
* - Radio Controls
* - Potentially FFTs or FIRs, if they affect scaling
*/
class UHD_RFNOC_API scalar_node_ctrl;
class scalar_node_ctrl : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<scalar_node_ctrl> sptr;
//! Undefined scaling
static const double SCALE_UNDEFINED;
/***********************************************************************
* Scaling controls
**********************************************************************/
/*! Returns the scaling factor for this block on input.
*
* A DUC block will return the scaling factor as determined by the duc
* stage.
*
* \param port Port Number
*/
virtual double get_input_scale_factor(size_t port = ANY_PORT);
/*! Returns the scaling factor for this block on output.
*
* A DDC block will return the scaling factor as determined by the ddc
* stage.
*
* \param port Port Number
*/
virtual double get_output_scale_factor(size_t port = ANY_PORT);
}; /* class scalar_node_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP */

View File

@ -1,25 +0,0 @@
//
// Copyright 2014-2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
class UHD_RFNOC_API siggen_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base
{
public:
UHD_RFNOC_BLOCK_OBJECT(siggen_block_ctrl)
}; /* class siggen_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP */

View File

@ -1,118 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_TX_BLOCK_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_TX_BLOCK_CTRL_BASE_HPP
#include <uhd/rfnoc/block_ctrl_base.hpp>
#include <uhd/rfnoc/sink_node_ctrl.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Extends block_ctrl_base with input capabilities.
*
* A sink block is an RFNoC block that can receive data at an input.
* We can use this block to transmit data (In RFNoC nomenclature, a
* transmit operation means streaming data to the device from the host).
*
* Every input is defined by a port definition (port_t).
*/
class UHD_RFNOC_API sink_block_ctrl_base;
class sink_block_ctrl_base : virtual public block_ctrl_base, virtual public sink_node_ctrl
{
public:
typedef boost::shared_ptr<sink_block_ctrl_base> sptr;
/***********************************************************************
* Stream signatures
**********************************************************************/
/*! Return the input stream signature for a given block port.
*
* The actual signature is determined by the current configuration
* and the block definition file. The value returned here is calculated
* on-the-fly and is only valid as long as the configuration does not
* change.
*
* \returns The stream signature for port \p block_port
* \throws uhd::runtime_error if \p block_port is not a valid port
*/
stream_sig_t get_input_signature(size_t block_port = 0) const;
/*! Return a list of valid input ports.
*/
std::vector<size_t> get_input_ports() const;
/***********************************************************************
* FPGA Configuration
**********************************************************************/
/*! Return the size of input buffer on a given block port.
*
* This is necessary for setting up flow control, among other things.
* Note: This does not query the block's settings register. The FIFO size
* is queried once during construction and cached.
*
* If the block port is not defined, it will return 0, and not throw.
*
* \param block_port The block port (0 through 15).
*
* Returns the size of the buffer in bytes.
*/
size_t get_fifo_size(size_t block_port = 0) const;
/*! Return the MTU size on a given block port.
*
* This is necessary for setting up transports, among other things.
*
* If the block port is not defined, it will return 0, and not throw.
*
* \param block_port The block port (0 through 15).
*
* Returns the MTU in bytes.
*/
size_t get_mtu(size_t block_port = 0) const;
/*! Configure flow control for incoming streams.
*
* If flow control is enabled for incoming streams, this block will periodically
* send out ACKs, telling the upstream block which packets have been consumed,
* so the upstream block can increase his flow control credit.
*
* In the default implementation, this just sets register SR_FLOW_CTRL_PKTS_PER_ACK
* accordingly.
*
* Override this function if your block has port-specific flow control settings.
*
* \param bytes Send an ACK after this many bytes have been consumed.
* Setting this to zero disables flow control acknowledgement.
* \param block_port Set up flow control for a stream coming in on this particular
* block port.
*/
virtual void configure_flow_control_in(
const size_t bytes, const size_t block_port = 0);
/*! Configure the behaviour for errors on incoming packets
* (e.g. sequence errors).
*
*
*/
virtual void set_error_policy(const std::string& policy);
protected:
/***********************************************************************
* Hooks
**********************************************************************/
/*! Like sink_node_ctrl::_request_input_port(), but also checks
* the port has an input signature.
*/
virtual size_t _request_input_port(
const size_t suggested_port, const uhd::device_addr_t& args) const;
}; /* class sink_block_ctrl_base */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_TX_BLOCK_CTRL_BASE_HPP */

View File

@ -1,117 +0,0 @@
//
// Copyright 2014-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/constants.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/rfnoc/sink_node_ctrl.hpp>
#include <boost/thread.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Abstract class for sink nodes.
*
* Sink nodes can have upstream blocks.
*/
class UHD_RFNOC_API sink_node_ctrl;
class sink_node_ctrl : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<sink_node_ctrl> sptr;
typedef std::map<size_t, boost::weak_ptr<sink_node_ctrl> > node_map_t;
typedef std::pair<size_t, boost::weak_ptr<sink_node_ctrl> > node_map_pair_t;
/***********************************************************************
* Sink block controls
**********************************************************************/
/*! Connect another node upstream of this node.
*
* *Note:* If additional settings are required to make this connection work,
* e.g. configure flow control, these need to be done separately.
*
* If the requested connection is not possible, this function will throw.
*
* \p upstream_node Pointer to the node class to connect
* \p port Suggested port number on this block to connect the upstream
* block to.
* \p args Any arguments that can be useful for determining the port number.
*
* \returns The actual port number used.
*/
size_t connect_upstream(node_ctrl_base::sptr upstream_node,
size_t port = ANY_PORT,
const uhd::device_addr_t& args = uhd::device_addr_t());
/*! Call this function to notify a node about its streamer activity.
*
* When \p active is set to true, this means this block is now part of
* an active tx streamer chain. Conversely, when set to false, this means
* the node has been removed from an tx streamer chain.
*/
virtual void set_tx_streamer(bool active, const size_t port);
protected:
/*! Ask for a port number to connect an upstream block to.
*
* Typically, this will be overridden for custom behaviour.
* The default is to return the suggested port, disregarding
* \p args, unless \p port == ANY_PORT, in which case the first
* unused input port is returned.
*
* When deriving this function for custom behaviour, consider:
* - The result is used to call register_upstream_node(), which
* has its own checks in place.
* - This function may throw if the arguments can't be resolved.
* The exception will propagate to the user space.
* - Alternatively, the function may return ANY_PORT to signify
* failure.
* - \p args and \p suggested_port should be treated as strong
* suggestions, but there's no reason to just return any valid
* port.
*
* *Note:* For reasons of thread safety, it is recommended to
* never, ever call this function directly. It will be used by
* connect_upstream() which will handle the connection process
* in a thread-safe manner.
*
* \param suggested_port Try and connect here.
* \param args When deciding on a port number, these arguments may be used.
*
* \returns A valid input port, or ANY_PORT on failure.
*/
virtual size_t _request_input_port(
const size_t suggested_port, const uhd::device_addr_t& args) const;
private:
/*! Makes connecting something to the input thread-safe.
*/
boost::mutex _input_mutex;
/*! Register a node upstream of this one (i.e., a node that can send data to this
* node).
*
* By definition, the upstream node must of type source_node_ctrl.
*
* This saves a *weak pointer* to the upstream node and checks the port is
* available. Will throw otherwise.
*
* \param upstream_node A pointer to the node instantiation
* \param port Port number the upstream node is connected to
*/
void _register_upstream_node(node_ctrl_base::sptr upstream_node, size_t port);
}; /* class sink_node_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP */

View File

@ -1,148 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RX_BLOCK_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_RX_BLOCK_CTRL_BASE_HPP
#include <uhd/rfnoc/block_ctrl_base.hpp>
#include <uhd/rfnoc/source_node_ctrl.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Extends block_ctrl_base with receive capabilities.
*
* In RFNoC nomenclature, a receive operation means streaming
* data from the device (the crossbar) to the host.
* If a block has receive capabilities, this means we can receive
* data *from* this block.
*/
class UHD_RFNOC_API source_block_ctrl_base;
class source_block_ctrl_base : virtual public block_ctrl_base,
virtual public source_node_ctrl
{
public:
typedef boost::shared_ptr<source_block_ctrl_base> sptr;
/***********************************************************************
* Streaming operations
**********************************************************************/
/*! Issue a stream command for this block.
*
* There is no guaranteed action for this command. The default implementation
* is to send this command to the next upstream block, or issue a warning if
* there is no upstream block registered.
*
* However, implementations of block_ctrl_base might choose to do whatever seems
* appropriate, including throwing exceptions. This may also be true for some
* stream commands and not for others (i.e. STREAM_MODE_START_CONTINUOUS may be
* implemented, and STREAM_MODE_NUM_SAMPS_AND_DONE may be not).
*
* This function does not check for infinite loops. Example: Say you have two blocks,
* which are both registered as upstream from one another. If they both use
* block_ctrl_base::issue_stream_cmd(), then the stream command will be passed from
* one block to another indefinitely. This will not happen if one the block's
* controller classes overrides this function and actually handles it.
*
* See also register_upstream_block().
*
* \param stream_cmd The stream command.
* \param chan Channel for which this command is meant (data shall be produced on this
* channel).
*/
virtual void issue_stream_cmd(
const uhd::stream_cmd_t& stream_cmd, const size_t chan = 0);
/***********************************************************************
* Stream signatures
**********************************************************************/
/*! Return the output stream signature for a given block port.
*
* The actual signature is determined by the current configuration
* and the block definition file. The value returned here is calculated
* on-the-fly and is only valid as long as the configuration does not
* change.
*
* \returns The stream signature for port \p block_port
* \throws uhd::runtime_error if \p block_port is not a valid port
*/
stream_sig_t get_output_signature(size_t block_port = 0) const;
/*! Return a list of valid output ports.
*/
std::vector<size_t> get_output_ports() const;
/***********************************************************************
* FPGA Configuration
**********************************************************************/
/*! Configures data flowing from port \p output_block_port to go to \p next_address
*
* \param next_address Address of the downstream block
* \param output_block_port Port for which this is valid
*
* In the default implementation, this will write the value in \p next_address
* to register SR_NEXT_DST of this blocks settings bus. The value will also
* have bit 16 set to 1, since some blocks require this to respect this value.
*/
virtual void set_destination(uint32_t next_address, size_t output_block_port = 0);
/*! Configure flow control for outgoing streams.
*
* In the default implementation, this just sets registers SR_FLOW_CTRL_BUF_SIZE
* and SR_FLOW_CTRL_ENABLE accordingly; \b block_port and \p sid are ignored.
*
* Override this function if your block has port-specific flow control settings.
*
* \param enable_output Enable flow control module's output. If disabled, no packets
* will be output regardless of flow control state. \param buf_size_bytes The size of
* the downstream block's input FIFO size in number of bytes. Setting this to zero
* disables byte based flow control. If both byte based flow control and the packet
* limit are set to zero, the block will then produce data as fast as it can. \b
* Warning: This can cause head-of-line blocking, and potentially lock up your device!
* \param lossless_link The link for the connection is lossless. Periodic sync
* packets will be disabled. \param pkt_limit Limit the maximum number of packets in
* flight. Setting this to zero disables packet limiting. Usually kept disabled except
* for special case connections (such as DMA) that support only a finite number of
* packets in flight. \param block_port Specify on which outgoing port this setting is
* valid. \param sid The SID for which this is valid. This is meant for cases where
* the outgoing block port is not sufficient to set the flow control, and as such is
* rarely used.
*/
virtual void configure_flow_control_out(const bool enable_output,
const bool lossless_link,
const size_t buf_size_bytes,
const size_t pkt_limit = 0,
const size_t block_port = 0,
const uhd::sid_t& sid = uhd::sid_t());
/*! Return the MTU size on a given block port.
*
* This is necessary for setting up transports, among other things.
*
* If the block port is not defined, it will return 0, and not throw.
*
* \param block_port The block port (0 through 15).
*
* Returns the MTU in bytes.
*/
size_t get_mtu(size_t block_port = 0) const;
protected:
/***********************************************************************
* Hooks
**********************************************************************/
/*! Like source_node_ctrl::_request_output_port(), but also checks if
* the port has an output signature.
*/
virtual size_t _request_output_port(
const size_t suggested_port, const uhd::device_addr_t& args) const;
}; /* class source_block_ctrl_base */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RX_BLOCK_CTRL_BASE_HPP */

View File

@ -1,106 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/constants.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/types/stream_cmd.hpp>
#include <boost/thread.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Abstract class for source nodes.
*
* Source nodes can have downstream blocks.
*/
class UHD_RFNOC_API source_node_ctrl;
class source_node_ctrl : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<source_node_ctrl> sptr;
typedef std::map<size_t, boost::weak_ptr<source_node_ctrl> > node_map_t;
typedef std::pair<size_t, boost::weak_ptr<source_node_ctrl> > node_map_pair_t;
/***********************************************************************
* Source block controls
**********************************************************************/
/*! Issue a stream command for this block.
* \param stream_cmd The stream command.
* \param chan Channel Index
*/
virtual void issue_stream_cmd(
const uhd::stream_cmd_t& stream_cmd, const size_t chan = 0) = 0;
/*! Connect another node downstream of this node.
*
* *Note:* If additional settings are required to make this connection work,
* e.g. configure flow control, these need to be done separately.
*
* If the requested connection is not possible, this function will throw.
*
* \p downstream_node Pointer to the node class to connect
* \p port Suggested port number on this block to connect the downstream
* block to.
* \p args Any arguments that can be useful for determining the port number.
*
* \returns The actual port number used.
*/
size_t connect_downstream(node_ctrl_base::sptr downstream_node,
size_t port = ANY_PORT,
const uhd::device_addr_t& args = uhd::device_addr_t());
/*! Call this function to notify a node about its streamer activity.
*
* When \p active is set to true, this means this block is now part of
* an active rx streamer chain. Conversely, when set to false, this means
* the node has been removed from an rx streamer chain.
*/
virtual void set_rx_streamer(bool active, const size_t port);
protected:
/*! Ask for a port number to connect a downstream block to.
*
* See sink_node_ctrl::_request_input_port(). This is the same
* for output.
*
* \param suggested_port Try and connect here.
* \param args When deciding on a port number, these arguments may be used.
*
* \returns A valid input port, or ANY_PORT on failure.
*/
virtual size_t _request_output_port(
const size_t suggested_port, const uhd::device_addr_t& args) const;
private:
/*! Makes connecting something to the output thread-safe.
*/
boost::mutex _output_mutex;
/*! Register a node downstream of this one (i.e., a node that receives data from this
* node).
*
* By definition, the upstream node must of type sink_node_ctrl.
*
* This saves a *weak pointer* to the downstream node and checks
* the port is available. Will throw otherwise.
*
* \param downstream_node A pointer to the node instantiation
* \param port Port number the downstream node is connected to
*/
void _register_downstream_node(node_ctrl_base::sptr downstream_node, size_t port);
}; /* class source_node_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP */

View File

@ -1,80 +0,0 @@
//
// Copyright 2014-2015 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP
#define INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP
#include <uhd/config.hpp>
#include <iostream>
namespace uhd { namespace rfnoc {
/*! Describes a stream signature for data going to or coming from
* RFNoC ports.
*
* The stream signature may depend on a block's configuration. Even
* so, some attributes may be left undefined (e.g., a FIFO block
* works for any item type, so it doesn't need to set it).
*/
class UHD_RFNOC_API stream_sig_t
{
public:
/***********************************************************************
* Structors
***********************************************************************/
stream_sig_t();
/***********************************************************************
* The stream signature attributes
***********************************************************************/
//! The data type of the individual items (e.g. 'sc16'). If undefined, set
// to empty.
std::string item_type;
//! The vector length in multiples of items. If undefined, set to zero.
size_t vlen;
//! Packet size in bytes. If undefined, set to zero.
size_t packet_size;
bool is_bursty;
/***********************************************************************
* Helpers
***********************************************************************/
//! Compact string representation
std::string to_string();
//! Pretty-print string representation
std::string to_pp_string();
//! Returns the number of bytes necessary to store one item.
// Note: The vector length is *not* considered here.
//
// \returns Number of bytes per item or 0 if the item type is
// undefined.
// \throws uhd::key_error if the item type is invalid.
size_t get_bytes_per_item() const;
/*! Check if an output with signature \p output_sig could
* stream to an input signature \p input_sig.
*
* \return true if streams are compatible
*/
static bool is_compatible(
const stream_sig_t& output_sig, const stream_sig_t& input_sig);
};
//! Shortcut for << stream_sig.to_string()
UHD_INLINE std::ostream& operator<<(std::ostream& out, stream_sig_t stream_sig)
{
out << stream_sig.to_string().c_str();
return out;
}
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP */

View File

@ -1,41 +0,0 @@
//
// Copyright 2015 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_TERMINATOR_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_TERMINATOR_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/node_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Abstract class for terminator nodes (i.e. nodes that terminate
* the flow graph).
*
* Terminator nodes have the following properties:
* - Data flowing into such a node is not propagated to any other node, and
* data coming out of this node originates in this node.
* - Chain commands are not propagated past this node.
*
* A block may be a terminator node, but have both upstream and downstream
* nodes. An example is the radio block, which can be used for Rx and Tx.
* Even if it's used for both, the data going into the radio block is not
* the data coming out.
*/
class UHD_RFNOC_API terminator_node_ctrl;
class terminator_node_ctrl : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<terminator_node_ctrl> sptr;
}; /* class terminator_node_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_TERMINATOR_NODE_CTRL_BASE_HPP */

View File

@ -1,60 +0,0 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP
#include <uhd/rfnoc/constants.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Tick-rate-aware node control
*
* A "rate" node is a streaming node is a point in the flow graph
* that is aware of tick rates (time base). Such nodes include:
* - Radio Controls
* - Data generating blocks that add time stamps
*/
class UHD_RFNOC_API tick_node_ctrl;
class tick_node_ctrl : virtual public node_ctrl_base
{
public:
/***********************************************************************
* Types
**********************************************************************/
typedef boost::shared_ptr<tick_node_ctrl> sptr;
/***********************************************************************
* Constants
**********************************************************************/
//! This value is used by rate nodes that don't actually set a rate themselves
static const double RATE_UNDEFINED;
/***********************************************************************
* Rate controls
**********************************************************************/
/*! Return a tick rate.
*
* This might be either a tick rate defined by this block (see also _get_tick_rate())
* or it's a tick rate defined by an adjacent block.
* In that case, performs a graph search to figure out the tick rate.
*/
double get_tick_rate(const std::set<node_ctrl_base::sptr>& _explored_nodes =
std::set<node_ctrl_base::sptr>());
protected:
virtual double _get_tick_rate()
{
return RATE_UNDEFINED;
};
}; /* class tick_node_ctrl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP */

View File

@ -1,54 +0,0 @@
//
// Copyright 2014-2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP
#define INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP
#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
namespace uhd { namespace rfnoc {
/*! \brief Block controller for the standard windowing RFNoC block.
*
* The standard windowing block has the following features:
* - One input- and output-port
* - Configurable window length and coefficients
* - Supports data type sc16 (16-Bit fix-point complex samples)
*
* This block requires packets to be the same size as the downstream FFT length.
* It will perform one window operation per incoming packet, treating it
* as a vector of samples.
*/
class UHD_RFNOC_API window_block_ctrl : public source_block_ctrl_base,
public sink_block_ctrl_base
{
public:
UHD_RFNOC_BLOCK_OBJECT(window_block_ctrl)
static const size_t MAX_COEFF_VAL = 32767;
static const uint32_t SR_WINDOW_LEN = 131; // Note: AXI config bus uses 129 & 130
static const uint32_t RB_MAX_WINDOW_LEN = 0;
static const uint32_t AXIS_WINDOW_LOAD = AXIS_CONFIG_BUS + 0; // 2*0+0
static const uint32_t AXIS_WINDOW_LOAD_TLAST = AXIS_CONFIG_BUS + 1; // 2*0+1
//! Configure the window coefficients
//
// \p coeffs size determines the window length. If it longer than
// the maximum window length, throws a uhd::value_error.
virtual void set_window(const std::vector<int>& coeffs) = 0;
//! Returns the maximum window length.
virtual size_t get_max_len() const = 0;
//! Returns the current window length.
virtual size_t get_window_len() const = 0;
}; /* class window_block_ctrl*/
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP */

View File

@ -6,6 +6,7 @@
#
UHD_INSTALL(FILES
adapter_id.hpp
bounded_buffer.hpp
bounded_buffer.ipp
buffer_pool.hpp

View File

@ -23,11 +23,6 @@ class UHD_API managed_buffer
public:
managed_buffer(void) : _ref_count(0), _buffer(NULL), _length(0)
{
#ifdef UHD_TXRX_DEBUG_PRINTS
_mb_num = s_buffer_count;
// From Boost website: atomic_count seems only to have precrement operator.
++s_buffer_count;
#endif
}
virtual ~managed_buffer(void) {}
@ -83,24 +78,11 @@ public:
return (int)_ref_count;
}
#ifdef UHD_TXRX_DEBUG_PRINTS
int num() const
{
return _mb_num;
}
#endif
protected:
void* _buffer;
size_t _length;
#ifdef UHD_TXRX_DEBUG_PRINTS
int _mb_num;
#endif
private:
#ifdef UHD_TXRX_DEBUG_PRINTS
static boost::detail::atomic_count s_buffer_count;
#endif
};
UHD_INLINE void intrusive_ptr_add_ref(managed_buffer* p)

View File

@ -1,40 +0,0 @@
//
// Copyright 2016 Ettus Research
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_UHD_ZERO_COPY_RECV_OFFLOAD_HPP
#define INCLUDED_UHD_ZERO_COPY_RECV_OFFLOAD_HPP
#include <uhd/config.hpp>
#include <uhd/transport/zero_copy.hpp>
#include <boost/shared_ptr.hpp>
namespace uhd { namespace transport {
/*!
* A threaded transport offload that is meant to relieve the main thread of
* the responsibility of making receive calls.
*/
class UHD_API zero_copy_recv_offload : public virtual zero_copy_if
{
public:
typedef boost::shared_ptr<zero_copy_recv_offload> sptr;
/*!
* This transport offload adds a receive thread in order to
* communicate with the underlying transport. It is meant to be
* used in cases where the main thread needs to be relieved of the burden
* of the underlying transport receive calls.
*
* \param transport a shared pointer to the transport interface
* \param timeout a general timeout for pushing and pulling on the bounded buffer
*/
static sptr make(zero_copy_if::sptr transport, const double timeout);
};
}} // namespace uhd::transport
#endif /* INCLUDED_ZERO_COPY_OFFLOAD_HPP */

View File

@ -1,17 +1,18 @@
#
# Copyright 2010-2011,2015-2016 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
UHD_INSTALL(FILES
byte_vector.hpp
device_addr.hpp
dict.ipp
dict.hpp
direction.hpp
eeprom.hpp
endianness.hpp
io_type.hpp
mac_addr.hpp
@ -20,7 +21,6 @@ UHD_INSTALL(FILES
ref_vector.hpp
sensors.hpp
serial.hpp
sid.hpp
stream_cmd.hpp
time_spec.hpp
tune_request.hpp

Some files were not shown because too many files have changed in this diff Show More