1 //
2 // Copyright 2019 Ettus Research, a National Instruments Brand
3 //
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 //
6
7 #include <uhd/exception.hpp>
8 #include <uhd/rfnoc/constants.hpp>
9 #include <uhd/rfnoc/defaults.hpp>
10 #include <uhd/rfnoc/mock_block.hpp>
11 #include <uhd/rfnoc/registry.hpp>
12 #include <uhd/utils/static.hpp>
13 #include <uhdlib/rfnoc/factory.hpp>
14 #include <unordered_map>
15 #include <boost/functional/hash.hpp>
16 #include <iomanip>
17 #include <iostream>
18 #include <sstream>
19
20 using namespace uhd::rfnoc;
21
22 /*! Pair type for device depended block definitions. */
23 using block_device_pair_t = std::pair<noc_id_t, device_type_t>;
24
25
26 ///////////////////////////////////////////////////////////////////////////////
27 // There are two registries:
28 // - The "direct" registry, which is for blocks that do not have a block
29 // descriptor file
30 // - The "descriptor" registry, which is for blocks that *do* have a block
31 // descriptor file
32 //
33 // This is the direct registry:
34 using block_direct_reg_t = std::unordered_map<block_device_pair_t,
35 block_factory_info_t,
36 boost::hash<block_device_pair_t>>;
37 UHD_SINGLETON_FCN(block_direct_reg_t, get_direct_block_registry);
38 //
39 // This is the descriptor registry:
40 using block_descriptor_reg_t =
41 std::unordered_map<std::string /* block_key */, registry::factory_t>;
42 UHD_SINGLETON_FCN(block_descriptor_reg_t, get_descriptor_block_registry);
43 ///////////////////////////////////////////////////////////////////////////////
44
45 /******************************************************************************
46 * Registry functions
47 *
48 * Note: Don't use UHD_LOG_*, since all of this can be executed in a static
49 * fashion.
50 *****************************************************************************/
register_block_direct(noc_id_t noc_id,device_type_t device_id,const std::string & block_name,bool mb_access,const std::string & timebase_clock,const std::string & ctrlport_clock,factory_t factory_fn)51 void registry::register_block_direct(noc_id_t noc_id,
52 device_type_t device_id,
53 const std::string& block_name,
54 bool mb_access,
55 const std::string& timebase_clock,
56 const std::string& ctrlport_clock,
57 factory_t factory_fn)
58 {
59 block_device_pair_t key{noc_id, device_id};
60 if (get_direct_block_registry().count(key)) {
61 std::cerr << "[REGISTRY] WARNING: Attempting to overwrite previously "
62 "registered RFNoC block with noc_id,device_id: "
63 << std::hex << "0x" << noc_id << ", 0x" << device_id << std::dec
64 << std::endl;
65 return;
66 }
67 get_direct_block_registry().emplace(key,
68 block_factory_info_t{block_name,
69 mb_access,
70 timebase_clock,
71 ctrlport_clock,
72 std::move(factory_fn)});
73 }
74
register_block_descriptor(const std::string & block_key,factory_t factory_fn)75 void registry::register_block_descriptor(
76 const std::string& block_key, factory_t factory_fn)
77 {
78 if (get_descriptor_block_registry().count(block_key)) {
79 std::cerr << "[REGISTRY] WARNING: Attempting to overwrite previously "
80 "registered RFNoC block with block key"
81 << block_key << std::endl;
82 return;
83 }
84 get_descriptor_block_registry().emplace(block_key, std::move(factory_fn));
85 }
86
87 /******************************************************************************
88 * Factory functions
89 *****************************************************************************/
get_block_factory(noc_id_t noc_id,device_type_t device_id)90 block_factory_info_t factory::get_block_factory(noc_id_t noc_id, device_type_t device_id)
91 {
92 // First, check the descriptor registry
93 // FIXME TODO
94
95 // Second, check the direct registry
96 block_device_pair_t key{noc_id, device_id};
97
98 if (!get_direct_block_registry().count(key)) {
99 key = block_device_pair_t(noc_id, ANY_DEVICE);
100 }
101 if (!get_direct_block_registry().count(key)) {
102 UHD_LOG_WARNING("RFNOC::BLOCK_FACTORY",
103 "Could not find block with Noc-ID " << std::hex << "0x" << key.first << ", 0x"
104 << key.second << std::dec);
105 key = block_device_pair_t(DEFAULT_NOC_ID, ANY_DEVICE);
106 }
107 return get_direct_block_registry().at(key);
108 }
109