mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
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:
parent
1ac6e6f561
commit
7d69dcdcc3
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
/*! \page page_rfnoc RFNoC Development Manual
|
||||
|
||||
\li \subpage page_rfnoc_descriptor_file
|
||||
|
||||
*/
|
||||
// vim:ft=doxygen:
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 */
|
||||
@ -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)
|
||||
@ -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
|
||||
)
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
@ -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 & 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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
<!--This defines one NoC-Block.-->
|
||||
<nocblock>
|
||||
<name>Schmidl & 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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
)
|
||||
)
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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:
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -6,6 +6,7 @@
|
||||
#
|
||||
|
||||
UHD_INSTALL(FILES
|
||||
adapter_id.hpp
|
||||
bounded_buffer.hpp
|
||||
bounded_buffer.ipp
|
||||
buffer_pool.hpp
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 */
|
||||
@ -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
Loading…
Reference in New Issue
Block a user