From fff4fd59b7b7995904ecb2b010f05f78e9d0a0de Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 30 May 2019 16:17:49 -0700 Subject: rfnoc: noc_block_base: Handle the tick_rate property internally All noc_block_base derivatives are now plugged into the tick rate system. Connected nodes can only have one tick rate among them. This implies there is also only ever one tick rate per block. set_tick_rate() is a protected API call which can be called by blocks such as radio blocks to actually set a tick rate. Other blocks would only ever read the tick rate, which is handled by the get_tick_rate() API call. --- host/lib/rfnoc/noc_block_base.cpp | 62 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'host/lib/rfnoc/noc_block_base.cpp') diff --git a/host/lib/rfnoc/noc_block_base.cpp b/host/lib/rfnoc/noc_block_base.cpp index 838e05e74..2bbf52928 100644 --- a/host/lib/rfnoc/noc_block_base.cpp +++ b/host/lib/rfnoc/noc_block_base.cpp @@ -4,12 +4,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include +#include #include #include -#include +#include using namespace uhd::rfnoc; +noc_block_base::make_args_t::~make_args_t() = default; + /****************************************************************************** * Structors *****************************************************************************/ @@ -19,7 +23,39 @@ noc_block_base::noc_block_base(make_args_ptr make_args) , _block_id(make_args->block_id) , _num_input_ports(make_args->num_input_ports) , _num_output_ports(make_args->num_output_ports) + , _clock_iface(make_args->clk_iface) { + // First, create one tick_rate property for every port + _tick_rate_props.reserve(get_num_input_ports() + get_num_output_ports()); + for (size_t input_port = 0; input_port < get_num_input_ports(); input_port++) { + _tick_rate_props.push_back(property_t(PROP_KEY_TICK_RATE, + DEFAULT_TICK_RATE, + {res_source_info::INPUT_EDGE, input_port})); + } + for (size_t output_port = 0; output_port < get_num_output_ports(); output_port++) { + _tick_rate_props.push_back(property_t(PROP_KEY_TICK_RATE, + DEFAULT_TICK_RATE, + {res_source_info::OUTPUT_EDGE, output_port})); + } + // Register all the tick_rate properties and create a default resolver + prop_ptrs_t prop_refs; + prop_refs.reserve(_tick_rate_props.size()); + for (auto& prop : _tick_rate_props) { + prop_refs.insert(&prop); + register_property(&prop); + } + for (auto& prop : _tick_rate_props) { + auto prop_refs_copy = prop_refs; + add_property_resolver( + {&prop}, std::move(prop_refs_copy), [this, source_prop = &prop]() { + for (property_t& tick_rate_prop : _tick_rate_props) { + tick_rate_prop = source_prop->get(); + } + this->_set_tick_rate(source_prop->get()); + }); + } + // Now enable this clock iface + _clock_iface->set_running(true); } noc_block_base::~noc_block_base() @@ -27,3 +63,27 @@ noc_block_base::~noc_block_base() // nop } + +void noc_block_base::set_tick_rate(const double tick_rate) +{ + if (_tick_rate == tick_rate) { + return; + } + // Update this node + _set_tick_rate(tick_rate); + // Now trigger property propagation + if (!_tick_rate_props.empty()) { + auto src_info = _tick_rate_props.at(0).get_src_info(); + set_property(PROP_KEY_TICK_RATE, tick_rate, src_info); + } +} + +void noc_block_base::_set_tick_rate(const double tick_rate) +{ + if (tick_rate == _tick_rate) { + return; + } + RFNOC_LOG_TRACE("Updating tick rate to " << (tick_rate / 1e6) << " MHz"); + _clock_iface->set_freq(tick_rate); + _tick_rate = tick_rate; +} -- cgit v1.2.3