USRP Hardware Driver and USRP Manual Version: 3.15.0.0-MacPorts-Release
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>
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
44namespace uhd {
45
46// TODO: These hints were added to boost 1.53.
47
49UHD_INLINE bool likely(bool expr)
50{
51#ifdef __GNUC__
52 return __builtin_expect(expr, true);
53#else
54 return expr;
55#endif
56}
57
59UHD_INLINE bool unlikely(bool expr)
60{
61#ifdef __GNUC__
62 return __builtin_expect(expr, false);
63#else
64 return expr;
65#endif
66}
67
75typedef uint32_t soft_reg_field_t;
76
77namespace soft_reg_field {
79{
80 return (field & 0xFF);
81}
82
84{
85 return ((field >> 8) & 0xFF);
86}
87
88template <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{
105public:
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
137template <typename reg_data_t, bool readable, bool writable>
139{
140public:
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
152 : _iface(NULL)
153 , _wr_addr(wr_addr)
154 , _rd_addr(rd_addr)
155 , _soft_copy(0)
156 , _flush_mode(mode)
157 {
158 }
159
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
302private:
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
314template <typename reg_data_t, bool readable, bool writable>
316 : public soft_register_t<reg_data_t, readable, writable>
317{
318public:
319 typedef boost::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable> > sptr;
320
324 : soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode)
325 , _mutex()
326 {
327 }
328
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
377private:
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
453namespace uhd {
454
456{
457public:
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{
478public:
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
557protected:
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) {
575 "cannot add two registers with the same name to regmap: " + name);
576 }
577 }
578 _reglist.push_back(&reg);
579 }
580
581private:
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{
600public:
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
710private:
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 */
Definition: soft_register.hpp:104
virtual bool is_writable()=0
virtual void initialize(wb_iface &iface, bool sync=false)=0
static UHD_INLINE soft_reg_t & cast(soft_register_base &reg)
Definition: soft_register.hpp:119
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:106
Definition: soft_register.hpp:317
soft_register_sync_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:329
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
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:341
UHD_INLINE void refresh()
Definition: soft_register.hpp:359
UHD_INLINE void flush()
Definition: soft_register.hpp:353
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:365
boost::shared_ptr< soft_register_sync_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:319
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:371
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:335
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:347
Definition: soft_register.hpp:139
soft_register_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:164
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:175
boost::shared_ptr< soft_register_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:141
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:262
UHD_INLINE void refresh()
Definition: soft_register.hpp:239
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:191
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:271
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:202
UHD_INLINE size_t get_bitwidth()
Definition: soft_register.hpp:280
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
UHD_INLINE void flush()
Definition: soft_register.hpp:211
UHD_INLINE bool is_readable()
Definition: soft_register.hpp:289
UHD_INLINE bool is_writable()
Definition: soft_register.hpp:297
Definition: soft_register.hpp:456
virtual ~soft_regmap_accessor_t()
Definition: soft_register.hpp:460
boost::shared_ptr< soft_regmap_accessor_t > sptr
Definition: soft_register.hpp:458
virtual soft_register_base & lookup(const std::string &path) const =0
virtual std::vector< std::string > enumerate() const =0
virtual const std::string & get_name() const =0
Definition: soft_register.hpp:599
boost::shared_ptr< soft_regmap_db_t > sptr
Definition: soft_register.hpp:601
void add(soft_regmap_t &regmap)
Definition: soft_register.hpp:624
soft_regmap_db_t(const std::string &name)
Definition: soft_register.hpp:611
const std::string & get_name() const
Definition: soft_register.hpp:616
void add(soft_regmap_db_t &db)
Definition: soft_register.hpp:633
virtual std::vector< std::string > enumerate() const
Definition: soft_register.hpp:696
soft_regmap_db_t()
Definition: soft_register.hpp:606
soft_register_base & lookup(const std::string &path) const
Definition: soft_register.hpp:653
Definition: soft_register.hpp:477
void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:496
virtual std::vector< std::string > enumerate() const
Definition: soft_register.hpp:548
virtual ~soft_regmap_t()
Definition: soft_register.hpp:480
soft_regmap_t(const std::string &name)
Definition: soft_register.hpp:479
virtual UHD_INLINE const std::string & get_name() const
Definition: soft_register.hpp:485
void flush()
Definition: soft_register.hpp:509
virtual soft_register_base & lookup(const std::string &name) const
Definition: soft_register.hpp:534
visibility_t
Definition: soft_register.hpp:558
@ PUBLIC
Definition: soft_register.hpp:559
UHD_INLINE void add_to_map(soft_register_base &reg, const std::string &name, const visibility_t visible=PRIVATE)
Definition: soft_register.hpp:566
void refresh()
Definition: soft_register.hpp:522
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:88
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:395
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:408
soft_register_sync_t< uint16_t, false, true > soft_reg16_wo_sync_t
Definition: soft_register.hpp:397
soft_register_sync_t< uint64_t, true, false > soft_reg64_ro_sync_t
Definition: soft_register.hpp:412
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:405
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:402
soft_register_t< uint32_t, true, true > soft_reg32_rw_t
Definition: soft_register.hpp:403
soft_register_sync_t< uint32_t, true, true > soft_reg32_rw_sync_t
Definition: soft_register.hpp:406
soft_register_t< uint64_t, true, false > soft_reg64_ro_t
Definition: soft_register.hpp:409
soft_register_sync_t< uint16_t, true, false > soft_reg16_ro_sync_t
Definition: soft_register.hpp:398
soft_register_t< uint16_t, false, true > soft_reg16_wo_t
Definition: soft_register.hpp:394
soft_register_sync_t< uint16_t, true, true > soft_reg16_rw_sync_t
Definition: soft_register.hpp:399
soft_register_t< uint16_t, true, true > soft_reg16_rw_t
Definition: soft_register.hpp:396
soft_register_sync_t< uint64_t, true, true > soft_reg64_rw_sync_t
Definition: soft_register.hpp:413
soft_register_sync_t< uint32_t, false, true > soft_reg32_wo_sync_t
Definition: soft_register.hpp:404
soft_reg_flush_mode_t
Definition: soft_register.hpp:130
@ OPTIMIZED_FLUSH
Definition: soft_register.hpp:130
@ ALWAYS_FLUSH
Definition: soft_register.hpp:130
soft_register_t< uint64_t, true, true > soft_reg64_rw_t
Definition: soft_register.hpp:410
soft_register_t< uint32_t, false, true > soft_reg32_wo_t
Definition: soft_register.hpp:401
soft_register_sync_t< uint64_t, false, true > soft_reg64_wo_sync_t
Definition: soft_register.hpp:411
#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