USRP Hardware Driver and USRP Manual  Version: 3.11.0.HEAD-0-g13c32cef
UHD and USRP Manual
soft_register.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2014 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 
8 #ifndef INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP
9 #define INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP
10 
11 #include <stdint.h>
12 #include <boost/noncopyable.hpp>
13 #include <uhd/types/wb_iface.hpp>
14 #include <uhd/exception.hpp>
16 #include <boost/thread/mutex.hpp>
17 #include <boost/thread/locks.hpp>
18 #include <boost/unordered_map.hpp>
19 #include <boost/tokenizer.hpp>
20 #include <boost/foreach.hpp>
21 #include <list>
22 
37 //==================================================================
38 // Soft Register Definition
39 //==================================================================
40 
41 #define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift) \
42  static const uhd::soft_reg_field_t name = (((shift & 0xFF) << 8) | (width & 0xFF))
43 
44 namespace uhd {
45 
46 //TODO: These hints were added to boost 1.53.
47 
49 UHD_INLINE bool likely(bool expr)
50 {
51 #ifdef __GNUC__
52  return __builtin_expect(expr, true);
53 #else
54  return expr;
55 #endif
56  }
57 
59 UHD_INLINE bool unlikely(bool expr)
60 {
61 #ifdef __GNUC__
62  return __builtin_expect(expr, false);
63 #else
64  return expr;
65 #endif
66 }
67 
75 typedef uint32_t soft_reg_field_t;
76 
77 namespace soft_reg_field {
78  UHD_INLINE size_t width(const soft_reg_field_t field) {
79  return (field & 0xFF);
80  }
81 
82  UHD_INLINE size_t shift(const soft_reg_field_t field) {
83  return ((field >> 8) & 0xFF);
84  }
85 
86  template<typename data_t>
87  UHD_INLINE data_t mask(const soft_reg_field_t field) {
88  static const data_t ONE = static_cast<data_t>(1);
89  //Behavior for the left shift operation is undefined in C++
90  //if the shift amount is >= bitwidth of the datatype
91  //So we treat that as a special case with a branch predicition hint
92  if (likely((sizeof(data_t)*8) != width(field)))
93  return ((ONE<<width(field))-ONE)<<shift(field);
94  else
95  return (0-ONE)<<shift(field);
96  }
97 }
98 
99 class soft_register_base : public boost::noncopyable {
100 public:
101  virtual ~soft_register_base() {}
102 
103  virtual void initialize(wb_iface& iface, bool sync = false) = 0;
104  virtual void flush() = 0;
105  virtual void refresh() = 0;
106  virtual size_t get_bitwidth() = 0;
107  virtual bool is_readable() = 0;
108  virtual bool is_writable() = 0;
109 
113  template <typename soft_reg_t>
114  UHD_INLINE static soft_reg_t& cast(soft_register_base& reg) {
115  soft_reg_t* ptr = dynamic_cast<soft_reg_t*>(&reg);
116  if (ptr) {
117  return *ptr;
118  } else {
119  throw uhd::type_error("failed to cast register to specified type");
120  }
121  }
122 };
123 
125 
131 template<typename reg_data_t, bool readable, bool writable>
133 public:
134  typedef boost::shared_ptr< soft_register_t<reg_data_t, readable, writable> > sptr;
135 
136  //Reserved field. Represents all bits in the register.
137  UHD_DEFINE_SOFT_REG_FIELD(REGISTER, sizeof(reg_data_t)*8, 0); //[WIDTH-1:0]
138 
143  wb_iface::wb_addr_type wr_addr,
144  wb_iface::wb_addr_type rd_addr,
145  soft_reg_flush_mode_t mode = ALWAYS_FLUSH):
146  _iface(NULL), _wr_addr(wr_addr), _rd_addr(rd_addr), _soft_copy(0), _flush_mode(mode)
147  {}
148 
153  explicit soft_register_t(
155  soft_reg_flush_mode_t mode = ALWAYS_FLUSH):
156  _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)
157  {}
158 
164  UHD_INLINE void initialize(wb_iface& iface, bool sync = false)
165  {
166  _iface = &iface;
167 
168  //Synchronize with hardware. For RW register, flush THEN refresh.
169  if (sync && writable) flush();
170  if (sync && readable) refresh();
171  }
172 
178  UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
179  {
180  _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field)) |
181  ((value << soft_reg_field::shift(field)) & soft_reg_field::mask<reg_data_t>(field));
182  }
183 
188  UHD_INLINE reg_data_t get(const soft_reg_field_t field)
189  {
190  return (_soft_copy & soft_reg_field::mask<reg_data_t>(field)) >> soft_reg_field::shift(field);
191  }
192 
197  {
198  if (writable && _iface) {
199  //If optimized flush then poke only if soft copy is dirty
200  //If flush mode is ALWAYS, the dirty flag should get optimized
201  //out by the compiler because it is never read
202  if (_flush_mode == ALWAYS_FLUSH || _soft_copy.is_dirty()) {
203  if (get_bitwidth() <= 16) {
204  _iface->poke16(_wr_addr, static_cast<uint16_t>(_soft_copy));
205  } else if (get_bitwidth() <= 32) {
206  _iface->poke32(_wr_addr, static_cast<uint32_t>(_soft_copy));
207  } else if (get_bitwidth() <= 64) {
208  _iface->poke64(_wr_addr, static_cast<uint64_t>(_soft_copy));
209  } else {
210  throw uhd::not_implemented_error("soft_register only supports up to 64 bits.");
211  }
212  _soft_copy.mark_clean();
213  }
214  } else {
215  throw uhd::not_implemented_error("soft_register is not writable or uninitialized.");
216  }
217  }
218 
223  {
224  if (readable && _iface) {
225  if (get_bitwidth() <= 16) {
226  _soft_copy = static_cast<reg_data_t>(_iface->peek16(_rd_addr));
227  } else if (get_bitwidth() <= 32) {
228  _soft_copy = static_cast<reg_data_t>(_iface->peek32(_rd_addr));
229  } else if (get_bitwidth() <= 64) {
230  _soft_copy = static_cast<reg_data_t>(_iface->peek64(_rd_addr));
231  } else {
232  throw uhd::not_implemented_error("soft_register only supports up to 64 bits.");
233  }
234  _soft_copy.mark_clean();
235  } else {
236  throw uhd::not_implemented_error("soft_register is not readable or uninitialized.");
237  }
238  }
239 
243  UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
244  {
245  set(field, value);
246  flush();
247  }
248 
252  UHD_INLINE reg_data_t read(const soft_reg_field_t field)
253  {
254  refresh();
255  return get(field);
256  }
257 
262  {
263  static const size_t BITS_IN_BYTE = 8;
264  return sizeof(reg_data_t) * BITS_IN_BYTE;
265  }
266 
271  {
272  return readable;
273  }
274 
279  {
280  return writable;
281  }
282 
283 private:
284  wb_iface* _iface;
285  const wb_iface::wb_addr_type _wr_addr;
286  const wb_iface::wb_addr_type _rd_addr;
287  dirty_tracked<reg_data_t> _soft_copy;
288  const soft_reg_flush_mode_t _flush_mode;
289 };
290 
295 template<typename reg_data_t, bool readable, bool writable>
296 class UHD_API soft_register_sync_t : public soft_register_t<reg_data_t, readable, writable> {
297 public:
298  typedef boost::shared_ptr< soft_register_sync_t<reg_data_t, readable, writable> > sptr;
299 
301  wb_iface::wb_addr_type wr_addr,
302  wb_iface::wb_addr_type rd_addr,
303  soft_reg_flush_mode_t mode = ALWAYS_FLUSH):
304  soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode), _mutex()
305  {}
306 
309  soft_reg_flush_mode_t mode = ALWAYS_FLUSH):
310  soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()
311  {}
312 
313  UHD_INLINE void initialize(wb_iface& iface, bool sync = false)
314  {
315  boost::lock_guard<boost::mutex> lock(_mutex);
317  }
318 
319  UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
320  {
321  boost::lock_guard<boost::mutex> lock(_mutex);
323  }
324 
325  UHD_INLINE reg_data_t get(const soft_reg_field_t field)
326  {
327  boost::lock_guard<boost::mutex> lock(_mutex);
329  }
330 
332  {
333  boost::lock_guard<boost::mutex> lock(_mutex);
335  }
336 
338  {
339  boost::lock_guard<boost::mutex> lock(_mutex);
341  }
342 
343  UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
344  {
345  boost::lock_guard<boost::mutex> lock(_mutex);
347  }
348 
349  UHD_INLINE reg_data_t read(const soft_reg_field_t field)
350  {
351  boost::lock_guard<boost::mutex> lock(_mutex);
353  }
354 
355 private:
356  boost::mutex _mutex;
357 };
358 
359 /*
360  * Register Shortcut Formats:
361  * - soft_reg<bits>_<mode>_t: Soft register object with an unsynchronized soft-copy.
362  * Thread unsafe but lightweight. Mostly const propagated.
363  * - soft_reg<bits>_<mode>_sync_t: Soft register object with a synchronized soft-copy.
364  * Thread safe but with memory/speed overhead.
365  * where:
366  * - <bits> = {16, 32 or 64}
367  * - <mode> = {wo(write-only), rw(read-write) or ro(read-only)}
368  *
369  */
370 
371 //16-bit shortcuts
378 //32-bit shortcuts
385 //64-bit shortcuts
392 
393 
394 /*
395  * Usage example
396  *
397  //===Define bit width, RW mode, and synchronization using base class===
398  class example_reg_t : public soft_reg32_wo_sync_t (or soft_reg32_wo_t) {
399  public:
400  //===Define all the fields===
401  UHD_DEFINE_SOFT_REG_FIELD(FIELD0, 1, 0); //[0]
402  UHD_DEFINE_SOFT_REG_FIELD(FIELD1, 15, 1); //[15:1]
403  UHD_DEFINE_SOFT_REG_FIELD(FIELD2, 16, 16); //[31:16]
404 
405  example_reg_t(): //ctor with no args
406  soft_reg32_wo_t(SR_CORE_EXAMPLE_REG_OFFSET)) //===Bind to offset===
407  {
408  //===Set Initial values===
409  set(FIELD0, 0);
410  set(FIELD1, 1);
411  set(FIELD2, 0xFFFF);
412  }
413  }; //===Full register definition encapsulated in one class===
414 
415  void main() {
416  example_reg_t reg_obj;
417  reg_obj.initialize(iface);
418  reg_obj.write(example_reg_t::FIELD2, 0x1234);
419 
420  example_reg_t::sptr reg_sptr = boost::make_shared<example_reg_t>();
421  reg_obj->initialize(iface);
422  reg_obj->write(example_reg_t::FIELD2, 0x1234);
423  }
424 */
425 }
426 
427 //==================================================================
428 // Soft Register Map and Database Definition
429 //==================================================================
430 
431 namespace uhd {
432 
434 public:
435  typedef boost::shared_ptr<soft_regmap_accessor_t> sptr;
436 
438  virtual soft_register_base& lookup(const std::string& path) const = 0;
439  virtual std::vector<std::string> enumerate() const = 0;
440  virtual const std::string& get_name() const = 0;
441 };
442 
453 class UHD_API soft_regmap_t : public soft_regmap_accessor_t, public boost::noncopyable {
454 public:
455  soft_regmap_t(const std::string& name) : _name(name) {}
456  virtual ~soft_regmap_t() {};
457 
461  virtual UHD_INLINE const std::string& get_name() const { return _name; }
462 
469  void initialize(wb_iface& iface, bool sync = false) {
470  boost::lock_guard<boost::mutex> lock(_mutex);
471  BOOST_FOREACH(soft_register_base* reg, _reglist) {
472  reg->initialize(iface, sync);
473  }
474  }
475 
481  void flush() {
482  boost::lock_guard<boost::mutex> lock(_mutex);
483  BOOST_FOREACH(soft_register_base* reg, _reglist) {
484  reg->flush();
485  }
486  }
487 
493  void refresh() {
494  boost::lock_guard<boost::mutex> lock(_mutex);
495  BOOST_FOREACH(soft_register_base* reg, _reglist) {
496  reg->refresh();
497  }
498  }
499 
504  virtual soft_register_base& lookup(const std::string& name) const {
505  regmap_t::const_iterator iter = _regmap.find(name);
506  if (iter != _regmap.end()) {
507  return *(iter->second);
508  } else {
509  throw uhd::runtime_error("register not found in map: " + name);
510  }
511  }
512 
517  virtual std::vector<std::string> enumerate() const {
518  std::vector<std::string> temp;
519  BOOST_FOREACH(const regmap_t::value_type& reg, _regmap) {
520  temp.push_back(_name + "/" + reg.first);
521  }
522  return temp;
523  }
524 
525 protected:
527  PUBLIC, //Is accessible through the soft_regmap_accessor_t interface
528  PRIVATE //Is NOT accessible through the soft_regmap_accessor_t interface
529  };
530 
534  UHD_INLINE void add_to_map(soft_register_base& reg, const std::string& name, const visibility_t visible = PRIVATE) {
535  boost::lock_guard<boost::mutex> lock(_mutex);
536  if (visible == PUBLIC) {
537  //Only add to the map if this register is publicly visible
538  if (not _regmap.insert(regmap_t::value_type(name, &reg)).second) {
539  throw uhd::assertion_error("cannot add two registers with the same name to regmap: " + name);
540  }
541  }
542  _reglist.push_back(&reg);
543  }
544 
545 private:
546  typedef boost::unordered_map<std::string, soft_register_base*> regmap_t;
547  typedef std::list<soft_register_base*> reglist_t;
548 
549  const std::string _name;
550  regmap_t _regmap; //For lookups
551  reglist_t _reglist; //To maintain order
552  boost::mutex _mutex;
553 };
554 
555 
562 class UHD_API soft_regmap_db_t : public soft_regmap_accessor_t, public boost::noncopyable {
563 public:
564  typedef boost::shared_ptr<soft_regmap_db_t> sptr;
565 
569  soft_regmap_db_t() : _name("") {}
570 
574  soft_regmap_db_t(const std::string& name) : _name(name) {}
575 
579  const std::string& get_name() const { return _name; }
580 
584  void add(soft_regmap_t& regmap) {
585  boost::lock_guard<boost::mutex> lock(_mutex);
586  _regmaps.push_back(&regmap);
587  }
588 
592  void add(soft_regmap_db_t& db) {
593  boost::lock_guard<boost::mutex> lock(_mutex);
594  if (&db == this) {
595  throw uhd::assertion_error("cannot add regmap db to itself" + _name);
596  } else {
597  _regmap_dbs.push_back(&db);
598  }
599  }
600 
611  soft_register_base& lookup(const std::string& path) const
612  {
613  //Turn the slash separated path string into tokens
614  std::list<std::string> tokens;
615  BOOST_FOREACH(
616  const std::string& node,
617  boost::tokenizer< boost::char_separator<char> >(path, boost::char_separator<char>("/")))
618  {
619  tokens.push_back(node);
620  }
621  if ((tokens.size() > 2 && tokens.front() == _name) || //If this is a nested DB
622  (tokens.size() > 1 && _name == "")) { //If this is a top-level DB
623  if (_name != "") tokens.pop_front();
624  if (tokens.size() == 2) { //2 tokens => regmap/register path
625  BOOST_FOREACH(const soft_regmap_accessor_t* regmap, _regmaps) {
626  if (regmap->get_name() == tokens.front()) {
627  return regmap->lookup(tokens.back());
628  }
629  }
630  throw uhd::runtime_error("could not find register map: " + path);
631  } else if (not _regmap_dbs.empty()) { //>2 tokens => <1 or more dbs>/regmap/register
632  //Reconstruct path from tokens
633  std::string newpath;
634  BOOST_FOREACH(const std::string& node, tokens) {
635  newpath += ("/" + node);
636  }
637  //Dispatch path to hierarchical DB
638  BOOST_FOREACH(const soft_regmap_accessor_t* db, _regmap_dbs) {
639  try {
640  return db->lookup(newpath.substr(1));
641  } catch (std::exception&) {
642  continue;
643  }
644  }
645  }
646  }
647  throw uhd::runtime_error("could not find register: " + path);
648  }
649 
653  virtual std::vector<std::string> enumerate() const {
654  std::vector<std::string> paths;
655  BOOST_FOREACH(const soft_regmap_accessor_t* regmap, _regmaps) {
656  const std::vector<std::string>& regs = regmap->enumerate();
657  paths.insert(paths.end(), regs.begin(), regs.end());
658  }
659  BOOST_FOREACH(const soft_regmap_accessor_t* db, _regmap_dbs) {
660  const std::vector<std::string>& regs = db->enumerate();
661  paths.insert(paths.end(), regs.begin(), regs.end());
662  }
663  return paths;
664  }
665 
666 private:
667  typedef std::list<soft_regmap_accessor_t*> db_t;
668 
669  const std::string _name;
670  db_t _regmaps;
671  db_t _regmap_dbs;
672  boost::mutex _mutex;
673 };
674 
675 } //namespace uhd
676 
677 #endif /* INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP */
void refresh()
Definition: soft_register.hpp:493
soft_register_sync_t< uint16_t, false, true > soft_reg16_wo_sync_t
Definition: soft_register.hpp:375
uint32_t soft_reg_field_t
Definition: soft_register.hpp:75
UHD_INLINE void flush()
Definition: soft_register.hpp:196
Definition: soft_register.hpp:124
soft_reg_flush_mode_t
Definition: soft_register.hpp:124
boost::shared_ptr< soft_register_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:134
Definition: soft_register.hpp:296
virtual void flush()=0
Definition: exception.hpp:106
soft_regmap_t(const std::string &name)
Definition: soft_register.hpp:455
UHD_INLINE bool unlikely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:59
UHD_INLINE void refresh()
Definition: soft_register.hpp:222
soft_register_t< uint64_t, false, true > soft_reg64_wo_t
Definition: soft_register.hpp:386
virtual std::vector< std::string > enumerate() const
Definition: soft_register.hpp:517
soft_register_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:153
#define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift)
Definition: soft_register.hpp:41
soft_register_t< uint32_t, true, false > soft_reg32_ro_t
Definition: soft_register.hpp:380
UHD_INLINE size_t get_bitwidth()
Definition: soft_register.hpp:261
virtual soft_register_base & lookup(const std::string &name) const
Definition: soft_register.hpp:504
soft_register_sync_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:307
UHD_INLINE bool is_writable()
Definition: soft_register.hpp:278
soft_register_sync_t< uint64_t, true, true > soft_reg64_rw_sync_t
Definition: soft_register.hpp:391
Definition: exception.hpp:91
Definition: soft_register.hpp:562
virtual std::vector< std::string > enumerate() const
Definition: soft_register.hpp:653
soft_register_sync_t< uint32_t, false, true > soft_reg32_wo_sync_t
Definition: soft_register.hpp:382
soft_register_t< uint32_t, false, true > soft_reg32_wo_t
Definition: soft_register.hpp:379
UHD_INLINE size_t width(const soft_reg_field_t field)
Definition: soft_register.hpp:78
Definition: soft_register.hpp:527
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:178
soft_regmap_db_t(const std::string &name)
Definition: soft_register.hpp:574
virtual ~soft_regmap_accessor_t()
Definition: soft_register.hpp:437
Definition: soft_register.hpp:132
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:188
Definition: build_info.hpp:14
soft_regmap_db_t()
Definition: soft_register.hpp:569
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:343
virtual std::vector< std::string > enumerate() const =0
virtual soft_register_base & lookup(const std::string &path) const =0
virtual ~soft_register_base()
Definition: soft_register.hpp:101
void flush()
Definition: soft_register.hpp:481
visibility_t
Definition: soft_register.hpp:526
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:164
virtual void refresh()=0
boost::shared_ptr< soft_register_sync_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:298
void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:469
virtual const std::string & get_name() const =0
soft_register_sync_t< uint64_t, true, false > soft_reg64_ro_sync_t
Definition: soft_register.hpp:390
virtual ~soft_regmap_t()
Definition: soft_register.hpp:456
soft_register_sync_t(wb_iface::wb_addr_type wr_addr, wb_iface::wb_addr_type rd_addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:300
boost::shared_ptr< soft_regmap_accessor_t > sptr
Definition: soft_register.hpp:435
Definition: soft_register.hpp:433
UHD_INLINE bool is_readable()
Definition: soft_register.hpp:270
#define UHD_INLINE
Definition: config.h:53
UHD_INLINE void flush()
Definition: soft_register.hpp:331
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:252
soft_register_t(wb_iface::wb_addr_type wr_addr, wb_iface::wb_addr_type rd_addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:142
soft_register_t< uint64_t, true, false > soft_reg64_ro_t
Definition: soft_register.hpp:387
boost::shared_ptr< soft_regmap_db_t > sptr
Definition: soft_register.hpp:564
Definition: soft_register.hpp:453
Definition: soft_register.hpp:99
soft_register_sync_t< uint32_t, true, false > soft_reg32_ro_sync_t
Definition: soft_register.hpp:383
Definition: exception.hpp:42
#define UHD_API
Definition: config.h:63
UHD_INLINE data_t mask(const soft_reg_field_t field)
Definition: soft_register.hpp:87
void add(soft_regmap_t &regmap)
Definition: soft_register.hpp:584
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:349
const std::string & get_name() const
Definition: soft_register.hpp:579
UHD_INLINE void refresh()
Definition: soft_register.hpp:337
soft_register_t< uint64_t, true, true > soft_reg64_rw_t
Definition: soft_register.hpp:388
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:243
soft_register_t< uint16_t, true, true > soft_reg16_rw_t
Definition: soft_register.hpp:374
Definition: exception.hpp:70
void add(soft_regmap_db_t &db)
Definition: soft_register.hpp:592
virtual void initialize(wb_iface &iface, bool sync=false)=0
soft_register_base & lookup(const std::string &path) const
Definition: soft_register.hpp:611
soft_register_sync_t< uint16_t, true, true > soft_reg16_rw_sync_t
Definition: soft_register.hpp:377
soft_register_sync_t< uint64_t, false, true > soft_reg64_wo_sync_t
Definition: soft_register.hpp:389
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:313
soft_register_t< uint16_t, false, true > soft_reg16_wo_t
Definition: soft_register.hpp:372
UHD_INLINE bool likely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:49
soft_register_sync_t< uint32_t, true, true > soft_reg32_rw_sync_t
Definition: soft_register.hpp:384
virtual UHD_INLINE const std::string & get_name() const
Definition: soft_register.hpp:461
UHD_INLINE void add_to_map(soft_register_base &reg, const std::string &name, const visibility_t visible=PRIVATE)
Definition: soft_register.hpp:534
UHD_INLINE size_t shift(const soft_reg_field_t field)
Definition: soft_register.hpp:82
Definition: soft_register.hpp:124
uint32_t wb_addr_type
Definition: wb_iface.hpp:23
static UHD_INLINE soft_reg_t & cast(soft_register_base &reg)
Definition: soft_register.hpp:114
Definition: wb_iface.hpp:19
soft_register_t< uint16_t, true, false > soft_reg16_ro_t
Definition: soft_register.hpp:373
soft_register_sync_t< uint16_t, true, false > soft_reg16_ro_sync_t
Definition: soft_register.hpp:376
soft_register_t< uint32_t, true, true > soft_reg32_rw_t
Definition: soft_register.hpp:381