From 1ed37cdfda93e430037ee4028ec5ac70ab223b1b Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 24 May 2019 14:46:39 -0700 Subject: rfnoc: Add block registry/factory and make_args - noc_block_base now has a ctor defined - The registry stores factory functions to the individual Noc-Block implementations --- host/lib/rfnoc/CMakeLists.txt | 2 + host/lib/rfnoc/noc_block_base.cpp | 18 ++++++++ host/lib/rfnoc/registry_factory.cpp | 88 +++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 host/lib/rfnoc/registry_factory.cpp (limited to 'host/lib/rfnoc') diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt index 2c13c1819..57a5253a7 100644 --- a/host/lib/rfnoc/CMakeLists.txt +++ b/host/lib/rfnoc/CMakeLists.txt @@ -1,6 +1,7 @@ # # Copyright 2014-2015,2017 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 # @@ -30,6 +31,7 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/rate_node_ctrl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ctrlport_endpoint.cpp ${CMAKE_CURRENT_SOURCE_DIR}/chdr_ctrl_endpoint.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/registry_factory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rx_stream_terminator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/scalar_node_ctrl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sink_block_ctrl_base.cpp diff --git a/host/lib/rfnoc/noc_block_base.cpp b/host/lib/rfnoc/noc_block_base.cpp index 3cacc455b..838e05e74 100644 --- a/host/lib/rfnoc/noc_block_base.cpp +++ b/host/lib/rfnoc/noc_block_base.cpp @@ -5,7 +5,25 @@ // #include +#include #include using namespace uhd::rfnoc; +/****************************************************************************** + * Structors + *****************************************************************************/ +noc_block_base::noc_block_base(make_args_ptr make_args) + : register_iface_holder(std::move(make_args->reg_iface)) + , _noc_id(make_args->noc_id) + , _block_id(make_args->block_id) + , _num_input_ports(make_args->num_input_ports) + , _num_output_ports(make_args->num_output_ports) +{ +} + +noc_block_base::~noc_block_base() +{ + // nop +} + diff --git a/host/lib/rfnoc/registry_factory.cpp b/host/lib/rfnoc/registry_factory.cpp new file mode 100644 index 000000000..cf7b897f7 --- /dev/null +++ b/host/lib/rfnoc/registry_factory.cpp @@ -0,0 +1,88 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace uhd::rfnoc; + +/////////////////////////////////////////////////////////////////////////////// +// There are two registries: +// - The "direct" registry, which is for blocks that do not have a block +// descriptor file +// - The "descriptor" registry, which is for blocks that *do* have a block +// descriptor file +// +// This is the direct registry: +using block_direct_reg_t = std::unordered_map>; +UHD_SINGLETON_FCN(block_direct_reg_t, get_direct_block_registry); +// +// This is the descriptor registry: +using block_descriptor_reg_t = + std::unordered_map; +UHD_SINGLETON_FCN(block_descriptor_reg_t, get_descriptor_block_registry); +/////////////////////////////////////////////////////////////////////////////// + +/****************************************************************************** + * Registry functions + * + * Note: Don't use UHD_LOG_*, since all of this can be executed in a static + * fashion. + *****************************************************************************/ +void registry::register_block_direct(noc_block_base::noc_id_t noc_id, + const std::string& block_name, + factory_t factory_fn) +{ + if (get_direct_block_registry().count(noc_id)) { + std::cerr + << "[REGISTRY] WARNING: Attempting to overwrite previously registered RFNoC " + "block with Noc-ID 0x" + << std::hex << noc_id << std::dec << std::endl; + return; + } + get_direct_block_registry().emplace( + noc_id, std::make_tuple(block_name, std::move(factory_fn))); +} + +void registry::register_block_descriptor( + const std::string& block_key, factory_t factory_fn) +{ + if (get_descriptor_block_registry().count(block_key)) { + std::cerr << "WARNING: Attempting to overwriting previously registered RFNoC " + "block with block key" + << block_key << std::endl; + return; + } + get_descriptor_block_registry().emplace(block_key, std::move(factory_fn)); +} + +/****************************************************************************** + * Factory functions + *****************************************************************************/ +std::pair factory::get_block_factory( + noc_block_base::noc_id_t noc_id) +{ + // First, check the descriptor registry + // FIXME TODO + + // Second, check the direct registry + if (!get_direct_block_registry().count(noc_id)) { + UHD_LOG_WARNING("RFNOC::BLOCK_FACTORY", + "Could not find block with Noc-ID " + << std::hex << std::setw(sizeof(noc_block_base::noc_id_t) * 2) << noc_id); + throw uhd::key_error("Block not found!"); + } + auto& block_info = get_direct_block_registry().at(noc_id); + return {std::get<1>(block_info), std::get<0>(block_info)}; +} -- cgit v1.2.3