USRP Hardware Driver and USRP Manual  Version: 3.15.0.HEAD-0-gaea0e2de
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 <uhd/exception.hpp>
12 #include <uhd/types/wb_iface.hpp>
14 #include <stdint.h>
15 #include <boost/foreach.hpp>
17 #include <boost/thread/locks.hpp>
18 #include <boost/thread/mutex.hpp>
19 #include <boost/tokenizer.hpp>
20 #include <boost/unordered_map.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 {
80  return (field & 0xFF);
81 }
82 
83 UHD_INLINE size_t shift(const soft_reg_field_t field)
84 {
85  return ((field >> 8) & 0xFF);
86 }
87 
88 template <typename data_t> UHD_INLINE data_t mask(const soft_reg_field_t field)
89 {
90  constexpr data_t ONE = static_cast<data_t>(1);
91  constexpr data_t ALL_ONES = ~static_cast<data_t>(0);
92  // Behavior for the left shift operation is undefined in C++
93  // if the shift amount is >= bitwidth of the datatype
94  // So we treat that as a special case with a branch predicition hint
95  if (likely((sizeof(data_t) * 8) != width(field))) {
96  return ((ONE << width(field)) - ONE) << shift(field);
97  } else {
98  return ALL_ONES << shift(field);
99  }
100 }
101 } // namespace soft_reg_field
102 
104 {
105 public:
106  virtual ~soft_register_base() {}
107 
108  virtual void initialize(wb_iface& iface, bool sync = false) = 0;
109  virtual void flush() = 0;
110  virtual void refresh() = 0;
111  virtual size_t get_bitwidth() = 0;
112  virtual bool is_readable() = 0;
113  virtual bool is_writable() = 0;
114 
118  template <typename soft_reg_t>
119  UHD_INLINE static soft_reg_t& cast(soft_register_base& reg)
120  {
121  soft_reg_t* ptr = dynamic_cast<soft_reg_t*>(&reg);
122  if (ptr) {
123  return *ptr;
124  } else {
125  throw uhd::type_error("failed to cast register to specified type");
126  }
127  }
128 };
129 
131 
137 template <typename reg_data_t, bool readable, bool writable>
139 {
140 public:
141  typedef boost::shared_ptr<soft_register_t<reg_data_t, readable, writable> > sptr;
142 
143  // Reserved field. Represents all bits in the register.
144  UHD_DEFINE_SOFT_REG_FIELD(REGISTER, sizeof(reg_data_t) * 8, 0); //[WIDTH-1:0]
145 
150  wb_iface::wb_addr_type rd_addr,
151  soft_reg_flush_mode_t mode = ALWAYS_FLUSH)
152  : _iface(NULL)
153  , _wr_addr(wr_addr)
154  , _rd_addr(rd_addr)
155  , _soft_copy(0)
156  , _flush_mode(mode)
157  {
158  }
159 
164  explicit soft_register_t(
165  wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode = ALWAYS_FLUSH)
166  : _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)
167  {
168  }
169 
175  UHD_INLINE void initialize(wb_iface& iface, bool sync = false)
176  {
177  _iface = &iface;
178 
179  // Synchronize with hardware. For RW register, flush THEN refresh.
180  if (sync && writable)
181  flush();
182  if (sync && readable)
183  refresh();
184  }
185 
191  UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
192  {
193  _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field))
194  | ((value << soft_reg_field::shift(field))
195  & soft_reg_field::mask<reg_data_t>(field));
196  }
197 
202  UHD_INLINE reg_data_t get(const soft_reg_field_t field)
203  {
204  return (_soft_copy & soft_reg_field::mask<reg_data_t>(field))
205  >> soft_reg_field::shift(field);
206  }
207 
212  {
213  if (writable && _iface) {
214  // If optimized flush then poke only if soft copy is dirty
215  // If flush mode is ALWAYS, the dirty flag should get optimized
216  // out by the compiler because it is never read
217  if (_flush_mode == ALWAYS_FLUSH || _soft_copy.is_dirty()) {
218  if (get_bitwidth() <= 16) {
219  _iface->poke16(_wr_addr, static_cast<uint16_t>(_soft_copy));
220  } else if (get_bitwidth() <= 32) {
221  _iface->poke32(_wr_addr, static_cast<uint32_t>(_soft_copy));
222  } else if (get_bitwidth() <= 64) {
223  _iface->poke64(_wr_addr, static_cast<uint64_t>(_soft_copy));
224  } else {
226  "soft_register only supports up to 64 bits.");
227  }
228  _soft_copy.mark_clean();
229  }
230  } else {
232  "soft_register is not writable or uninitialized.");
233  }
234  }
235 
240  {
241  if (readable && _iface) {
242  if (get_bitwidth() <= 16) {
243  _soft_copy = static_cast<reg_data_t>(_iface->peek16(_rd_addr));
244  } else if (get_bitwidth() <= 32) {
245  _soft_copy = static_cast<reg_data_t>(_iface->peek32(_rd_addr));
246  } else if (get_bitwidth() <= 64) {
247  _soft_copy = static_cast<reg_data_t>(_iface->peek64(_rd_addr));
248  } else {
250  "soft_register only supports up to 64 bits.");
251  }
252  _soft_copy.mark_clean();
253  } else {
255  "soft_register is not readable or uninitialized.");
256  }
257  }
258 
262  UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
263  {
264  set(field, value);
265  flush();
266  }
267 
271  UHD_INLINE reg_data_t read(const soft_reg_field_t field)
272  {
273  refresh();
274  return get(field);
275  }
276 
281  {
282  static const size_t BITS_IN_BYTE = 8;
283  return sizeof(reg_data_t) * BITS_IN_BYTE;
284  }
285 
290  {
291  return readable;
292  }
293 
298  {
299  return writable;
300  }
301 
302 private:
303  wb_iface* _iface;
304  const wb_iface::wb_addr_type _wr_addr;
305  const wb_iface::wb_addr_type _rd_addr;
306  dirty_tracked<reg_data_t> _soft_copy;
307  const soft_reg_flush_mode_t _flush_mode;
308 };
309 
314 template <typename reg_data_t, bool readable, bool writable>
316  : public soft_register_t<reg_data_t, readable, writable>
317 {
318 public:
319  typedef boost::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable> > sptr;
320 
322  wb_iface::wb_addr_type rd_addr,
323  soft_reg_flush_mode_t mode = ALWAYS_FLUSH)
324  : soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode)
325  , _mutex()
326  {
327  }
328 
330  wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode = ALWAYS_FLUSH)
331  : soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()
332  {
333  }
334 
335  UHD_INLINE void initialize(wb_iface& iface, bool sync = false)
336  {
337  boost::lock_guard<boost::mutex> lock(_mutex);
339  }
340 
341  UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
342  {
343  boost::lock_guard<boost::mutex> lock(_mutex);
345  }
346 
347  UHD_INLINE reg_data_t get(const soft_reg_field_t field)
348  {
349  boost::lock_guard<boost::mutex> lock(_mutex);
351  }
352 
354  {
355  boost::lock_guard<boost::mutex> lock(_mutex);
357  }
358 
360  {
361  boost::lock_guard<boost::mutex> lock(_mutex);
363  }
364 
365  UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
366  {
367  boost::lock_guard<boost::mutex> lock(_mutex);
369  }
370 
371  UHD_INLINE reg_data_t read(const soft_reg_field_t field)
372  {
373  boost::lock_guard<boost::mutex> lock(_mutex);
375  }
376 
377 private:
378  boost::mutex _mutex;
379 };
380 
381 /*
382  * Register Shortcut Formats:
383  * - soft_reg<bits>_<mode>_t: Soft register object with an unsynchronized soft-copy.
384  * Thread unsafe but lightweight. Mostly const propagated.
385  * - soft_reg<bits>_<mode>_sync_t: Soft register object with a synchronized soft-copy.
386  * Thread safe but with memory/speed overhead.
387  * where:
388  * - <bits> = {16, 32 or 64}
389  * - <mode> = {wo(write-only), rw(read-write) or ro(read-only)}
390  *
391  */
392 
393 // 16-bit shortcuts
400 // 32-bit shortcuts
407 // 64-bit shortcuts
414 
415 
416 /*
417  * Usage example
418  *
419  //===Define bit width, RW mode, and synchronization using base class===
420  class example_reg_t : public soft_reg32_wo_sync_t (or soft_reg32_wo_t) {
421  public:
422  //===Define all the fields===
423  UHD_DEFINE_SOFT_REG_FIELD(FIELD0, 1, 0); //[0]
424  UHD_DEFINE_SOFT_REG_FIELD(FIELD1, 15, 1); //[15:1]
425  UHD_DEFINE_SOFT_REG_FIELD(FIELD2, 16, 16); //[31:16]
426 
427  example_reg_t(): //ctor with no args
428  soft_reg32_wo_t(SR_CORE_EXAMPLE_REG_OFFSET)) //===Bind to offset===
429  {
430  //===Set Initial values===
431  set(FIELD0, 0);
432  set(FIELD1, 1);
433  set(FIELD2, 0xFFFF);
434  }
435  }; //===Full register definition encapsulated in one class===
436 
437  void main() {
438  example_reg_t reg_obj;
439  reg_obj.initialize(iface);
440  reg_obj.write(example_reg_t::FIELD2, 0x1234);
441 
442  example_reg_t::sptr reg_sptr = boost::make_shared<example_reg_t>();
443  reg_obj->initialize(iface);
444  reg_obj->write(example_reg_t::FIELD2, 0x1234);
445  }
446 */
447 } // namespace uhd
448 
449 //==================================================================
450 // Soft Register Map and Database Definition
451 //==================================================================
452 
453 namespace uhd {
454 
456 {
457 public:
458  typedef boost::shared_ptr<soft_regmap_accessor_t> sptr;
459 
461  virtual soft_register_base& lookup(const std::string& path) const = 0;
462  virtual std::vector<std::string> enumerate() const = 0;
463  virtual const std::string& get_name() const = 0;
464 };
465 
477 {
478 public:
479  soft_regmap_t(const std::string& name) : _name(name) {}
480  virtual ~soft_regmap_t(){};
481 
485  virtual UHD_INLINE const std::string& get_name() const
486  {
487  return _name;
488  }
489 
496  void initialize(wb_iface& iface, bool sync = false)
497  {
498  boost::lock_guard<boost::mutex> lock(_mutex);
499  BOOST_FOREACH (soft_register_base* reg, _reglist) {
500  reg->initialize(iface, sync);
501  }
502  }
503 
509  void flush()
510  {
511  boost::lock_guard<boost::mutex> lock(_mutex);
512  BOOST_FOREACH (soft_register_base* reg, _reglist) {
513  reg->flush();
514  }
515  }
516 
522  void refresh()
523  {
524  boost::lock_guard<boost::mutex> lock(_mutex);
525  BOOST_FOREACH (soft_register_base* reg, _reglist) {
526  reg->refresh();
527  }
528  }
529 
534  virtual soft_register_base& lookup(const std::string& name) const
535  {
536  regmap_t::const_iterator iter = _regmap.find(name);
537  if (iter != _regmap.end()) {
538  return *(iter->second);
539  } else {
540  throw uhd::runtime_error("register not found in map: " + name);
541  }
542  }
543 
548  virtual std::vector<std::string> enumerate() const
549  {
550  std::vector<std::string> temp;
551  BOOST_FOREACH (const regmap_t::value_type& reg, _regmap) {
552  temp.push_back(_name + "/" + reg.first);
553  }
554  return temp;
555  }
556 
557 protected:
559  PUBLIC, // Is accessible through the soft_regmap_accessor_t interface
560  PRIVATE // Is NOT accessible through the soft_regmap_accessor_t interface
561  };
562 
567  const std::string& name,
568  const visibility_t visible = PRIVATE)
569  {
570  boost::lock_guard<boost::mutex> lock(_mutex);
571  if (visible == PUBLIC) {
572  // Only add to the map if this register is publicly visible
573  if (not _regmap.insert(regmap_t::value_type(name, &reg)).second) {
574  throw uhd::assertion_error(
575  "cannot add two registers with the same name to regmap: " + name);
576  }
577  }
578  _reglist.push_back(&reg);
579  }
580 
581 private:
582  typedef boost::unordered_map<std::string, soft_register_base*> regmap_t;
583  typedef std::list<soft_register_base*> reglist_t;
584 
585  const std::string _name;
586  regmap_t _regmap; // For lookups
587  reglist_t _reglist; // To maintain order
588  boost::mutex _mutex;
589 };
590 
591 
599 {
600 public:
601  typedef boost::shared_ptr<soft_regmap_db_t> sptr;
602 
606  soft_regmap_db_t() : _name("") {}
607 
611  soft_regmap_db_t(const std::string& name) : _name(name) {}
612 
616  const std::string& get_name() const
617  {
618  return _name;
619  }
620 
624  void add(soft_regmap_t& regmap)
625  {
626  boost::lock_guard<boost::mutex> lock(_mutex);
627  _regmaps.push_back(&regmap);
628  }
629 
634  {
635  boost::lock_guard<boost::mutex> lock(_mutex);
636  if (&db == this) {
637  throw uhd::assertion_error("cannot add regmap db to itself" + _name);
638  } else {
639  _regmap_dbs.push_back(&db);
640  }
641  }
642 
653  soft_register_base& lookup(const std::string& path) const
654  {
655  // Turn the slash separated path string into tokens
656  std::list<std::string> tokens;
657  BOOST_FOREACH (const std::string& node,
658  boost::tokenizer<boost::char_separator<char> >(
659  path, boost::char_separator<char>("/"))) {
660  tokens.push_back(node);
661  }
662  if ((tokens.size() > 2 && tokens.front() == _name) || // If this is a nested DB
663  (tokens.size() > 1 && _name == "")) { // If this is a top-level DB
664  if (_name != "")
665  tokens.pop_front();
666  if (tokens.size() == 2) { // 2 tokens => regmap/register path
667  BOOST_FOREACH (const soft_regmap_accessor_t* regmap, _regmaps) {
668  if (regmap->get_name() == tokens.front()) {
669  return regmap->lookup(tokens.back());
670  }
671  }
672  throw uhd::runtime_error("could not find register map: " + path);
673  } else if (not _regmap_dbs
674  .empty()) { //>2 tokens => <1 or more dbs>/regmap/register
675  // Reconstruct path from tokens
676  std::string newpath;
677  BOOST_FOREACH (const std::string& node, tokens) {
678  newpath += ("/" + node);
679  }
680  // Dispatch path to hierarchical DB
681  BOOST_FOREACH (const soft_regmap_accessor_t* db, _regmap_dbs) {
682  try {
683  return db->lookup(newpath.substr(1));
684  } catch (std::exception&) {
685  continue;
686  }
687  }
688  }
689  }
690  throw uhd::runtime_error("could not find register: " + path);
691  }
692 
696  virtual std::vector<std::string> enumerate() const
697  {
698  std::vector<std::string> paths;
699  BOOST_FOREACH (const soft_regmap_accessor_t* regmap, _regmaps) {
700  const std::vector<std::string>& regs = regmap->enumerate();
701  paths.insert(paths.end(), regs.begin(), regs.end());
702  }
703  BOOST_FOREACH (const soft_regmap_accessor_t* db, _regmap_dbs) {
704  const std::vector<std::string>& regs = db->enumerate();
705  paths.insert(paths.end(), regs.begin(), regs.end());
706  }
707  return paths;
708  }
709 
710 private:
711  typedef std::list<soft_regmap_accessor_t*> db_t;
712 
713  const std::string _name;
714  db_t _regmaps;
715  db_t _regmap_dbs;
716  boost::mutex _mutex;
717 };
718 
719 } // namespace uhd
720 
721 #endif /* INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP */
void refresh()
Definition: soft_register.hpp:522
soft_register_sync_t< uint16_t, false, true > soft_reg16_wo_sync_t
Definition: soft_register.hpp:397
uint32_t soft_reg_field_t
Definition: soft_register.hpp:75
UHD_INLINE void flush()
Definition: soft_register.hpp:211
Definition: soft_register.hpp:130
soft_reg_flush_mode_t
Definition: soft_register.hpp:130
Definition: soft_register.hpp:315
virtual void flush()=0
Definition: exception.hpp:158
soft_regmap_t(const std::string &name)
Definition: soft_register.hpp:479
UHD_INLINE bool unlikely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:59
UHD_INLINE void refresh()
Definition: soft_register.hpp:239
soft_register_t< uint64_t, false, true > soft_reg64_wo_t
Definition: soft_register.hpp:408
virtual std::vector< std::string > enumerate() const
Definition: soft_register.hpp:548
soft_register_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:164
boost::noncopyable noncopyable
Definition: noncopyable.hpp:46
boost::shared_ptr< soft_register_sync_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:319
#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:402
UHD_INLINE size_t get_bitwidth()
Definition: soft_register.hpp:280
virtual soft_register_base & lookup(const std::string &name) const
Definition: soft_register.hpp:534
soft_register_sync_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:329
UHD_INLINE bool is_writable()
Definition: soft_register.hpp:297
soft_register_sync_t< uint64_t, true, true > soft_reg64_rw_sync_t
Definition: soft_register.hpp:413
Definition: exception.hpp:133
Definition: soft_register.hpp:598
virtual std::vector< std::string > enumerate() const
Definition: soft_register.hpp:696
soft_register_sync_t< uint32_t, false, true > soft_reg32_wo_sync_t
Definition: soft_register.hpp:404
soft_register_t< uint32_t, false, true > soft_reg32_wo_t
Definition: soft_register.hpp:401
UHD_INLINE size_t width(const soft_reg_field_t field)
Definition: soft_register.hpp:78
Definition: soft_register.hpp:559
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:191
soft_regmap_db_t(const std::string &name)
Definition: soft_register.hpp:611
virtual ~soft_regmap_accessor_t()
Definition: soft_register.hpp:460
Definition: soft_register.hpp:138
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:202
Definition: build_info.hpp:13
soft_regmap_db_t()
Definition: soft_register.hpp:606
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:365
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:106
void flush()
Definition: soft_register.hpp:509
visibility_t
Definition: soft_register.hpp:558
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:175
virtual void refresh()=0
void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:496
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:412
virtual ~soft_regmap_t()
Definition: soft_register.hpp:480
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:321
boost::shared_ptr< soft_regmap_accessor_t > sptr
Definition: soft_register.hpp:458
Definition: soft_register.hpp:455
UHD_INLINE bool is_readable()
Definition: soft_register.hpp:289
#define UHD_INLINE
Definition: config.h:53
boost::shared_ptr< soft_register_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:141
UHD_INLINE void flush()
Definition: soft_register.hpp:353
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:271
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:149
soft_register_t< uint64_t, true, false > soft_reg64_ro_t
Definition: soft_register.hpp:409
boost::shared_ptr< soft_regmap_db_t > sptr
Definition: soft_register.hpp:601
Definition: soft_register.hpp:476
Definition: soft_register.hpp:103
soft_register_sync_t< uint32_t, true, false > soft_reg32_ro_sync_t
Definition: soft_register.hpp:405
Definition: exception.hpp:49
#define UHD_API
Definition: config.h:68
UHD_INLINE data_t mask(const soft_reg_field_t field)
Definition: soft_register.hpp:88
void add(soft_regmap_t &regmap)
Definition: soft_register.hpp:624
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:371
const std::string & get_name() const
Definition: soft_register.hpp:616
UHD_INLINE void refresh()
Definition: soft_register.hpp:359
soft_register_t< uint64_t, true, true > soft_reg64_rw_t
Definition: soft_register.hpp:410
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:262
soft_register_t< uint16_t, true, true > soft_reg16_rw_t
Definition: soft_register.hpp:396
Definition: exception.hpp:97
void add(soft_regmap_db_t &db)
Definition: soft_register.hpp:633
virtual void initialize(wb_iface &iface, bool sync=false)=0
soft_register_base & lookup(const std::string &path) const
Definition: soft_register.hpp:653
soft_register_sync_t< uint16_t, true, true > soft_reg16_rw_sync_t
Definition: soft_register.hpp:399
soft_register_sync_t< uint64_t, false, true > soft_reg64_wo_sync_t
Definition: soft_register.hpp:411
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:335
soft_register_t< uint16_t, false, true > soft_reg16_wo_t
Definition: soft_register.hpp:394
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:406
virtual UHD_INLINE const std::string & get_name() const
Definition: soft_register.hpp:485
UHD_INLINE void add_to_map(soft_register_base &reg, const std::string &name, const visibility_t visible=PRIVATE)
Definition: soft_register.hpp:566
UHD_INLINE size_t shift(const soft_reg_field_t field)
Definition: soft_register.hpp:83
Definition: soft_register.hpp:130
uint32_t wb_addr_type
Definition: wb_iface.hpp:22
static UHD_INLINE soft_reg_t & cast(soft_register_base &reg)
Definition: soft_register.hpp:119
Definition: wb_iface.hpp:18
soft_register_t< uint16_t, true, false > soft_reg16_ro_t
Definition: soft_register.hpp:395
soft_register_sync_t< uint16_t, true, false > soft_reg16_ro_sync_t
Definition: soft_register.hpp:398
soft_register_t< uint32_t, true, true > soft_reg32_rw_t
Definition: soft_register.hpp:403