USRP Hardware Driver and Device Manual  Version: 4.11.0.0-0-g0d7ed3b1
UHD and USRP Manual
mock_block.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2019 Ettus Research, a National Instruments Brand
3 //
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 //
6 
7 #pragma once
8 
9 #include <uhd/config.hpp>
10 #include <uhd/property_tree.hpp>
11 #include <uhd/rfnoc/defaults.hpp>
15 #include <uhd/types/time_spec.hpp>
16 #include <uhd/utils/log.hpp>
17 #include <unordered_map>
18 #include <boost/format.hpp>
19 #include <vector>
20 
21 namespace uhd { namespace rfnoc {
22 
28 {
29 public:
30  mock_reg_iface_t() = default;
31  ~mock_reg_iface_t() override = default;
32 
33  /**************************************************************************
34  * API
35  *************************************************************************/
36  void poke32(uint32_t addr, uint32_t data, uhd::time_spec_t time, bool ack) override
37  {
38  write_memory[addr] = data;
39  _poke_cb(addr, data, time, ack);
40  }
41 
42  void multi_poke32(const std::vector<uint32_t> addrs,
43  const std::vector<uint32_t> data,
44  uhd::time_spec_t time,
45  bool ack) override
46  {
47  if (addrs.size() != data.size()) {
48  throw uhd::value_error("addrs and data vectors must be of the same length");
49  }
50  for (size_t i = 0; i < addrs.size(); i++) {
51  poke32(addrs[i], data[i], time, ack);
52  }
53  }
54 
55  void block_poke32(uint32_t first_addr,
56  const std::vector<uint32_t> data,
57  uhd::time_spec_t timestamp,
58  bool ack) override
59  {
60  for (size_t i = 0; i < data.size(); i++) {
61  poke32(first_addr + 4 * i, data[i], timestamp, ack);
62  }
63  }
64 
65  void burst_poke32(uint32_t addr,
66  const std::vector<uint32_t> data,
67  uhd::time_spec_t timestamp,
68  bool ack) override
69  {
70  for (size_t i = 0; i < data.size(); i++) {
71  poke32(addr, data[i], timestamp, ack);
72  }
73  }
74 
75  uint32_t peek32(uint32_t addr, uhd::time_spec_t time) override
76  {
77  _peek_cb(addr, time);
78  try {
79  return read_memory.at(addr);
80  } catch (const std::out_of_range&) {
81  throw uhd::runtime_error(
82  str(boost::format("No data defined for address: 0x%04X") % addr));
83  }
84  }
85 
86  std::vector<uint32_t> block_peek32(
87  uint32_t first_addr, size_t length, uhd::time_spec_t time) override
88  {
89  std::vector<uint32_t> result(length, 0);
90  for (size_t i = 0; i < length; ++i) {
91  result[i] = peek32(first_addr + i * 4, time);
92  }
93  return result;
94  }
95 
96  std::vector<uint32_t> burst_peek32(
97  uint32_t addr, size_t length, uhd::time_spec_t time) override
98  {
99  std::vector<uint32_t> result(length, 0);
100  for (size_t i = 0; i < length; ++i) {
101  result[i] = peek32(addr, time);
102  }
103  return result;
104  }
105 
106  std::optional<uint32_t> poll32(uint32_t addr,
107  uint32_t data,
108  uint32_t mask,
109  uhd::time_spec_t /* timeout */,
111  bool ack = false) override
112  {
113  if (force_timeout) {
114  throw uhd::op_timeout("timeout");
115  }
116 
117  const uint32_t reg_val = peek32(addr, time);
118  if ((reg_val & mask) == data) {
119  UHD_LOG_INFO("MOCK_REG_IFACE", "poll32() successful at addr " << addr);
120  } else {
121  UHD_LOG_INFO("MOCK_REG_IFACE", "poll32() not successful at addr " << addr);
122  }
123  return ack ? std::optional<uint32_t>(reg_val) : std::nullopt;
124  }
125 
126  void sleep(uhd::time_spec_t /*duration*/, bool /*ack*/) override
127  {
128  // nop
129  }
130 
132  {
133  // nop
134  }
135 
136  void register_async_msg_handler(async_msg_callback_t /*callback_f*/) override
137  {
138  // nop
139  }
140 
141  void set_policy(const std::string& name, const uhd::device_addr_t& args) override
142  {
143  UHD_LOG_INFO("MOCK_REG_IFACE",
144  "Requested to set policy for " << name << " to " << args.to_string());
145  }
146 
147  uint16_t get_src_epid() const override
148  {
149  return 0;
150  }
151 
152  uint16_t get_port_num() const override
153  {
154  return 0;
155  }
156 
157  void define_custom_register_space(const uint32_t /*start_addr*/,
158  const uint32_t /*length*/,
159  std::function<void(uint32_t, uint32_t)> /*poke_fn*/,
160  std::function<uint32_t(uint32_t)> /*peek_fn*/) override
161  {
162  // nop
163  }
164 
166  {
167  // Mock implementation - return zero stats
168  return {};
169  }
170 
171  bool force_timeout = false;
172 
174  std::unordered_map<uint32_t, uint32_t> read_memory;
178  std::unordered_map<uint32_t, uint32_t> write_memory;
179 
180 protected:
181  virtual void _poke_cb(
182  uint32_t /*addr*/, uint32_t /*data*/, uhd::time_spec_t /*time*/, bool /*ack*/)
183  {
184  }
185 
186  virtual void _peek_cb(uint32_t /*addr*/, uhd::time_spec_t /*time*/) {}
187 };
188 
192 {
193  friend class get_mock_block;
195  std::shared_ptr<mock_reg_iface_t> reg_iface;
196 
199 
205  template <typename block_type = noc_block_base>
206  std::shared_ptr<block_type> get_block()
207  {
208  return std::dynamic_pointer_cast<block_type>(factory(std::move(make_args)));
209  }
210 
213 
214  // Note: The make args would ideally be captured by the factory function,
215  // but std::functions need to be CopyConstructible, and this struct doesn't,
216  // so it needs to live out here in the open.
218 };
219 
223  const size_t num_inputs = 1,
224  const size_t num_outputs = 1,
225  const uhd::device_addr_t& args = uhd::device_addr_t(),
226  const size_t mtu = 8000,
227  const device_type_t device_id = ANY_DEVICE,
228  std::shared_ptr<mock_reg_iface_t> client_reg_iface = nullptr,
229  mb_controller::sptr mbc = nullptr);
230 
231 }}; // namespace uhd::rfnoc
Definition: device_addr.hpp:39
std::string to_string(void) const
std::shared_ptr< property_tree > sptr
Definition: property_tree.hpp:224
std::shared_ptr< mb_controller > sptr
Definition: mb_controller.hpp:33
Definition: mock_block.hpp:28
uint16_t get_src_epid() const override
Definition: mock_block.hpp:147
std::vector< uint32_t > burst_peek32(uint32_t addr, size_t length, uhd::time_spec_t time) override
Definition: mock_block.hpp:96
std::optional< uint32_t > poll32(uint32_t addr, uint32_t data, uint32_t mask, uhd::time_spec_t, uhd::time_spec_t time=uhd::time_spec_t::ASAP, bool ack=false) override
Definition: mock_block.hpp:106
void burst_poke32(uint32_t addr, const std::vector< uint32_t > data, uhd::time_spec_t timestamp, bool ack) override
Definition: mock_block.hpp:65
~mock_reg_iface_t() override=default
std::unordered_map< uint32_t, uint32_t > write_memory
Definition: mock_block.hpp:178
void block_poke32(uint32_t first_addr, const std::vector< uint32_t > data, uhd::time_spec_t timestamp, bool ack) override
Definition: mock_block.hpp:55
std::vector< uint32_t > block_peek32(uint32_t first_addr, size_t length, uhd::time_spec_t time) override
Definition: mock_block.hpp:86
register_iface_stats get_stats() const override
Definition: mock_block.hpp:165
void multi_poke32(const std::vector< uint32_t > addrs, const std::vector< uint32_t > data, uhd::time_spec_t time, bool ack) override
Definition: mock_block.hpp:42
uint32_t peek32(uint32_t addr, uhd::time_spec_t time) override
Definition: mock_block.hpp:75
virtual void _peek_cb(uint32_t, uhd::time_spec_t)
Definition: mock_block.hpp:186
void set_policy(const std::string &name, const uhd::device_addr_t &args) override
Definition: mock_block.hpp:141
std::unordered_map< uint32_t, uint32_t > read_memory
All pokes end up writing to this map.
Definition: mock_block.hpp:174
void register_async_msg_validator(async_msg_validator_t) override
Definition: mock_block.hpp:131
void define_custom_register_space(const uint32_t, const uint32_t, std::function< void(uint32_t, uint32_t)>, std::function< uint32_t(uint32_t)>) override
Definition: mock_block.hpp:157
void sleep(uhd::time_spec_t, bool) override
Definition: mock_block.hpp:126
virtual void _poke_cb(uint32_t, uint32_t, uhd::time_spec_t, bool)
Definition: mock_block.hpp:181
void poke32(uint32_t addr, uint32_t data, uhd::time_spec_t time, bool ack) override
Definition: mock_block.hpp:36
void register_async_msg_handler(async_msg_callback_t) override
Definition: mock_block.hpp:136
uint16_t get_port_num() const override
Definition: mock_block.hpp:152
std::unique_ptr< make_args_int_t, make_args_deleter > make_args_ptr
Opaque pointer to the constructor arguments with custom deleter.
Definition: noc_block_base.hpp:73
std::shared_ptr< noc_block_base > sptr
Definition: noc_block_base.hpp:44
Definition: register_iface.hpp:78
std::function< bool(uint32_t addr, const std::vector< uint32_t > &data)> async_msg_validator_t
Definition: register_iface.hpp:93
std::function< void(uint32_t addr, const std::vector< uint32_t > &data, std::optional< uint64_t >)> async_msg_callback_t
Definition: register_iface.hpp:109
Definition: time_spec.hpp:31
static constexpr double ASAP
Definition: time_spec.hpp:34
#define UHD_API
Definition: config.h:87
#define UHD_LOG_INFO(component,...)
Definition: log.h:53
uint16_t device_type_t
Device Type.
Definition: defaults.hpp:56
UHD_API mock_block_container get_mock_block(const noc_id_t noc_id, const size_t num_inputs=1, const size_t num_outputs=1, const uhd::device_addr_t &args=uhd::device_addr_t(), const size_t mtu=8000, const device_type_t device_id=ANY_DEVICE, std::shared_ptr< mock_reg_iface_t > client_reg_iface=nullptr, mb_controller::sptr mbc=nullptr)
uint32_t noc_id_t
Definition: defaults.hpp:52
UHD_INLINE data_t mask(const soft_reg_field_t field)
Definition: soft_register.hpp:86
Definition: build_info.hpp:12
Definition: exception.hpp:251
Definition: mock_block.hpp:192
std::shared_ptr< block_type > get_block()
Use this to retrieve a reference to the block controller.
Definition: mock_block.hpp:206
uhd::property_tree::sptr tree
Reference to the prop tree object the block sees.
Definition: mock_block.hpp:198
std::function< noc_block_base::sptr(noc_block_base::make_args_ptr)> factory
Factory to get the block. Use get_block() instead.
Definition: mock_block.hpp:212
std::shared_ptr< mock_reg_iface_t > reg_iface
Reference to the register interface object.
Definition: mock_block.hpp:195
noc_block_base::make_args_ptr make_args
Definition: mock_block.hpp:217
Definition: register_iface.hpp:49
Definition: exception.hpp:132
Definition: exception.hpp:108