diff options
Diffstat (limited to 'host')
| -rw-r--r-- | host/include/uhd/rfnoc/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/include/uhd/rfnoc/defaults.hpp | 1 | ||||
| -rw-r--r-- | host/include/uhd/rfnoc/switchboard_block_control.hpp | 48 | ||||
| -rw-r--r-- | host/lib/rfnoc/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/rfnoc/switchboard_block_control.cpp | 130 | 
5 files changed, 181 insertions, 0 deletions
diff --git a/host/include/uhd/rfnoc/CMakeLists.txt b/host/include/uhd/rfnoc/CMakeLists.txt index 3249b51f3..7a1602f90 100644 --- a/host/include/uhd/rfnoc/CMakeLists.txt +++ b/host/include/uhd/rfnoc/CMakeLists.txt @@ -45,6 +45,7 @@ UHD_INSTALL(FILES      null_block_control.hpp      radio_control.hpp      split_stream_block_control.hpp +    switchboard_block_control.hpp      vector_iir_block_control.hpp      window_block_control.hpp diff --git a/host/include/uhd/rfnoc/defaults.hpp b/host/include/uhd/rfnoc/defaults.hpp index 9964467d3..ac230b57d 100644 --- a/host/include/uhd/rfnoc/defaults.hpp +++ b/host/include/uhd/rfnoc/defaults.hpp @@ -83,6 +83,7 @@ static const noc_id_t FOSPHOR_BLOCK        = 0x666F0000;  static const noc_id_t LOGPWR_BLOCK         = 0x4C500000;  static const noc_id_t MOVING_AVERAGE_BLOCK = 0xAAD20000;  static const noc_id_t SPLIT_STREAM_BLOCK   = 0x57570000; +static const noc_id_t SWITCHBOARD_BLOCK    = 0xBE110000;  static const noc_id_t RADIO_BLOCK          = 0x12AD1000;  static const noc_id_t VECTOR_IIR_BLOCK     = 0x11120000;  static const noc_id_t WINDOW_BLOCK         = 0xD0530000; diff --git a/host/include/uhd/rfnoc/switchboard_block_control.hpp b/host/include/uhd/rfnoc/switchboard_block_control.hpp new file mode 100644 index 000000000..0b0b4c722 --- /dev/null +++ b/host/include/uhd/rfnoc/switchboard_block_control.hpp @@ -0,0 +1,48 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#pragma once + +#include <uhd/config.hpp> +#include <uhd/rfnoc/noc_block_base.hpp> + +namespace uhd { namespace rfnoc { + +/*! Switchboard Block Control Class + * + * The Switchboard Block is an RFNoC block that routes any single input to any + * single output. Routing is 1 to 1, that is, an input port can only be connected  + * to one output port, and vice versa. + * + * INIT: This block is initialized with only input port 0 connected to output  + *       port 0. + * + * NOTE: This block is not intended to switch during the transmission of packets. + *       Data on disconnected inputs will stall. + */ +class UHD_API switchboard_block_control : public noc_block_base +{ +public: +    RFNOC_DECLARE_BLOCK(switchboard_block_control) + +    // Block registers +    static const uint32_t REG_BLOCK_SIZE; + +    static const uint32_t REG_DEMUX_SELECT_ADDR; +    static const uint32_t REG_MUX_SELECT_ADDR; + +    /*! Connects an input to an output +     * +     * Bridges an input to an output. Any existing connections on +     * either the input or output will be dropped. +     * +     * \param input Index of the input port. +     * \param output Index of the output port. +     */ +    virtual void connect(const size_t input, const size_t output) = 0; +}; + +}} // namespace uhd::rfnoc diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt index 63bdccf4d..a9c3c9ed0 100644 --- a/host/lib/rfnoc/CMakeLists.txt +++ b/host/lib/rfnoc/CMakeLists.txt @@ -53,6 +53,7 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/null_block_control.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/radio_control_impl.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/split_stream_block_control.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/switchboard_block_control.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/vector_iir_block_control.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/window_block_control.cpp  ) diff --git a/host/lib/rfnoc/switchboard_block_control.cpp b/host/lib/rfnoc/switchboard_block_control.cpp new file mode 100644 index 000000000..229c224e9 --- /dev/null +++ b/host/lib/rfnoc/switchboard_block_control.cpp @@ -0,0 +1,130 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include <uhd/rfnoc/defaults.hpp> +#include <uhd/rfnoc/multichan_register_iface.hpp> +#include <uhd/rfnoc/property.hpp> +#include <uhd/rfnoc/registry.hpp> +#include <uhd/rfnoc/switchboard_block_control.hpp> + +using namespace uhd::rfnoc; + +// Register offsets +const uint32_t switchboard_block_control::REG_BLOCK_SIZE        = 8; +const uint32_t switchboard_block_control::REG_DEMUX_SELECT_ADDR = 0; +const uint32_t switchboard_block_control::REG_MUX_SELECT_ADDR   = 4; + +// User properties +const char* const PROP_KEY_INPUT_SELECT = "input_select"; +const char* const PROP_KEY_OUTPUT_SELECT = "output_select"; + +class switchboard_block_control_impl : public switchboard_block_control +{ +public: +    RFNOC_BLOCK_CONSTRUCTOR(switchboard_block_control), +        _num_input_ports(get_num_input_ports()), +        _num_output_ports(get_num_output_ports()), +        _switchboard_reg_iface(*this, 0, REG_BLOCK_SIZE) +    { +        UHD_ASSERT_THROW(_num_input_ports > 0 && _num_output_ports > 0); + +        _register_props(); + +        // Configure property propagation and action forwarding behavior. +        set_prop_forwarding_policy(forwarding_policy_t::USE_MAP); +        set_action_forwarding_policy(forwarding_policy_t::USE_MAP); + +        _update_forwarding_map(); +    } + +    void connect(const size_t input, const size_t output) +    { +        set_property<int>(PROP_KEY_INPUT_SELECT, static_cast<int>(input), output); +        set_property<int>(PROP_KEY_OUTPUT_SELECT, static_cast<int>(output), input); + +        _update_forwarding_map(); +    } + +private: +    const size_t _num_input_ports; +    const size_t _num_output_ports; + +    void _register_props() +    { +        _input_select.reserve(_num_output_ports); +        _output_select.reserve(_num_input_ports); + +        // Register _input_select properties +        for (size_t output_port = 0; output_port < _num_output_ports; output_port++) { +            _input_select.emplace_back(property_t<int>( +                PROP_KEY_INPUT_SELECT, 0, {res_source_info::USER, output_port})); + +            register_property(&_input_select.back(), [this, output_port]() { +                int select_val = _input_select.at(output_port).get(); +                if (select_val < 0  +                    || static_cast<unsigned int>(select_val) >= _num_input_ports) +                    throw uhd::value_error("Index out of bounds"); +                _switchboard_reg_iface.poke32( +                    REG_MUX_SELECT_ADDR, select_val, output_port); +            }); +        } + +        // Register _output_select properties +        for (size_t input_port = 0; input_port < _num_input_ports; input_port++) { +            _output_select.emplace_back(property_t<int>( +                PROP_KEY_OUTPUT_SELECT, 0, {res_source_info::USER, input_port})); + +            register_property(&_output_select.back(), [this, input_port]() { +                int select_val = _output_select.at(input_port).get(); +                if (select_val < 0 +                    || static_cast<unsigned int>(select_val) >= _num_output_ports) +                    throw uhd::value_error("Index out of bounds"); +                _switchboard_reg_iface.poke32( +                    REG_DEMUX_SELECT_ADDR, select_val, input_port); +            }); +        } +    } + +    void _update_forwarding_map() +    { +        node_t::forwarding_map_t prop_fwd_map; +        node_t::forwarding_map_t action_fwd_map; + +        // Property propagation scheme: +        //   Connected inputs and outputs will propagate to each other. +        //   Unconnected inputs and outputs do not propagate. +        for (size_t input_port = 0; input_port < _num_input_ports; input_port++) { +            size_t linked_output_port = _output_select.at(input_port).get(); +            size_t linked_input_port  = _input_select.at(linked_output_port).get(); +            if (linked_input_port == input_port) { +                prop_fwd_map.insert({{res_source_info::INPUT_EDGE, linked_input_port}, +                    {{res_source_info::OUTPUT_EDGE, linked_output_port}}}); +                prop_fwd_map.insert({{res_source_info::OUTPUT_EDGE, linked_output_port}, +                    {{res_source_info::INPUT_EDGE, linked_input_port}}}); +                action_fwd_map.insert({{res_source_info::INPUT_EDGE, linked_input_port}, +                    {{res_source_info::OUTPUT_EDGE, linked_output_port}}}); +                action_fwd_map.insert({{res_source_info::OUTPUT_EDGE, linked_output_port}, +                    {{res_source_info::INPUT_EDGE, linked_input_port}}}); +            } +        } +        set_prop_forwarding_map(prop_fwd_map); +        set_action_forwarding_map(action_fwd_map); +    } + +    /************************************************************************** +     * Attributes +     *************************************************************************/ +    std::vector<property_t<int>> _input_select; +    std::vector<property_t<int>> _output_select; + +    /************************************************************************** +     * Register Interface +     *************************************************************************/ +    multichan_register_iface _switchboard_reg_iface; +}; + +UHD_RFNOC_BLOCK_REGISTER_DIRECT( +    switchboard_block_control, SWITCHBOARD_BLOCK, "Switchboard", CLOCK_KEY_GRAPH, "bus_clk")  | 
