diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-06-13 13:34:11 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:27 -0800 |
commit | 3da938f1242219fdf993576dcfdce7440a63c044 (patch) | |
tree | 145b8999ba2c72ebc8e1115ceedd6a8a3a0d2210 /host/lib/rfnoc/rfnoc_graph.cpp | |
parent | de246ea6174e3a6d5fe0dd554d5208f24c2932bb (diff) | |
download | uhd-3da938f1242219fdf993576dcfdce7440a63c044.tar.gz uhd-3da938f1242219fdf993576dcfdce7440a63c044.tar.bz2 uhd-3da938f1242219fdf993576dcfdce7440a63c044.zip |
rfnoc: Add clock selection to blocks
During registration, blocks must now specify which clock they are using
for the timebase (i.e., for timed commands) and for the ctrlport (this
is used to determine the length of sleeps and polls). For example, the
X300 provides bus_clk and radio_clk; typically, the former is used for
the control port, and the latter for the timebase clock.
Another virtual clock is called "__graph__", and it means the clock is
derived from property propagation via the graph.
The actual clocks are provided by the mb_iface. It has two new API
calls: get_timebase_clock() and get_ctrlport_clock(), which take an
argument as to which clock exactly is requested. On block
initialization, those clock_iface objects are copied into the block
controller.
The get_tick_rate() API call for blocks now exclusively checks the
timebase clock_iface, and will no longer cache the current tick rate in
a separate _tick_rate member variable. Block controllers can't manually
modify the clock_iface, unless they also have access to the
mb_controller (like the radio block), and that mb_controller has
provided said access.
This commit also adds the clock selection API changes to the DDC block,
the Null block, and the default block.
Diffstat (limited to 'host/lib/rfnoc/rfnoc_graph.cpp')
-rw-r--r-- | host/lib/rfnoc/rfnoc_graph.cpp | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/host/lib/rfnoc/rfnoc_graph.cpp b/host/lib/rfnoc/rfnoc_graph.cpp index 5b2277284..04b13a374 100644 --- a/host/lib/rfnoc/rfnoc_graph.cpp +++ b/host/lib/rfnoc/rfnoc_graph.cpp @@ -184,27 +184,47 @@ private: // Iterate through and register each of the blocks in this mboard for (size_t portno = 0; portno < num_blocks; ++portno) { auto noc_id = mb_cz->get_noc_id(portno + first_block_port); - auto block_factory_pair = factory::get_block_factory(noc_id); + auto block_factory_info = factory::get_block_factory(noc_id); auto block_info = mb_cz->get_block_info(portno + first_block_port); block_id_t block_id(mb_idx, - block_factory_pair.second, - block_count_map[block_factory_pair.second]++); - auto clk_iface = std::make_shared<clock_iface>(block_id.to_string() + "_clock"); + block_factory_info.block_name, + block_count_map[block_factory_info.block_name]++); + // Get access to the clock interface objects. We have some rules + // here: + // - The ctrlport clock must always be provided through the + // BSP via mb_iface + // - The timebase clock can be set to "graph", which means the + // block takes care of the timebase itself (via property + // propagation). In that case, we generate a clock iface + // object on the fly here. + // - In all other cases, the BSP must provide us that clock + // iface object through the mb_iface + auto ctrlport_clk_iface = + mb.get_clock_iface(block_factory_info.ctrlport_clk); + auto tb_clk_iface = (block_factory_info.timebase_clk == CLOCK_KEY_GRAPH) ? + std::make_shared<clock_iface>(CLOCK_KEY_GRAPH) : + mb.get_clock_iface(block_factory_info.timebase_clk); + // A "graph" clock is always "running" + if (block_factory_info.timebase_clk == CLOCK_KEY_GRAPH) { + tb_clk_iface->set_running(true); + } auto block_reg_iface = _gsm->get_block_register_iface(ctrl_sep_addr, portno, - *clk_iface.get(), - *clk_iface.get()); + *ctrlport_clk_iface.get(), + *tb_clk_iface.get()); auto make_args_uptr = std::make_unique<noc_block_base::make_args_t>(); make_args_uptr->noc_id = noc_id; make_args_uptr->block_id = block_id; make_args_uptr->num_input_ports = block_info.num_inputs; make_args_uptr->num_output_ports = block_info.num_outputs; make_args_uptr->reg_iface = block_reg_iface; - make_args_uptr->clk_iface = clk_iface; + make_args_uptr->tb_clk_iface = tb_clk_iface; + make_args_uptr->ctrlport_clk_iface = ctrlport_clk_iface; make_args_uptr->mb_control = (factory::has_requested_mb_access(noc_id) ? _mb_controllers.at(mb_idx) : nullptr); make_args_uptr->tree = _tree->subtree("/mboards/0"); /* FIXME Get the block's subtree */ make_args_uptr->args = dev_addr; // TODO filter the device args - _block_registry->register_block(block_factory_pair.first(std::move(make_args_uptr))); + _block_registry->register_block( + block_factory_info.factory_fn(std::move(make_args_uptr))); _xbar_block_config[block_id.to_string()] = { portno, noc_id, block_id.get_block_count()}; } |