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