8 #ifndef INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP
9 #define INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP
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>
41 #define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift) \
42 static const uhd::soft_reg_field_t name = (((shift & 0xFF) << 8) | (width & 0xFF))
52 return __builtin_expect(expr,
true);
62 return __builtin_expect(expr,
false);
77 namespace soft_reg_field {
80 return (field & 0xFF);
85 return ((field >> 8) & 0xFF);
88 template <
typename data_t>
91 constexpr data_t ONE =
static_cast<data_t
>(1);
92 constexpr data_t ALL_ONES = ~static_cast<data_t>(0);
97 return ((ONE <<
width(field)) - ONE) <<
shift(field);
99 return ALL_ONES <<
shift(field);
119 template <
typename soft_reg_t>
122 soft_reg_t* ptr =
dynamic_cast<soft_reg_t*
>(®);
138 template <
typename reg_data_t,
bool readable,
bool writable>
142 typedef boost::shared_ptr<soft_register_t<reg_data_t, readable, writable> >
sptr;
167 : _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)
181 if (sync && writable)
183 if (sync && readable)
194 _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field))
196 & soft_reg_field::mask<reg_data_t>(field));
205 return (_soft_copy & soft_reg_field::mask<reg_data_t>(field))
214 if (writable && _iface) {
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));
227 "soft_register only supports up to 64 bits.");
229 _soft_copy.mark_clean();
233 "soft_register is not writable or uninitialized.");
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));
251 "soft_register only supports up to 64 bits.");
253 _soft_copy.mark_clean();
256 "soft_register is not readable or uninitialized.");
283 static const size_t BITS_IN_BYTE = 8;
284 return sizeof(reg_data_t) * BITS_IN_BYTE;
315 template <
typename reg_data_t,
bool readable,
bool writable>
320 typedef boost::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable> >
sptr;
325 :
soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode)
332 :
soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()
338 boost::lock_guard<boost::mutex> lock(_mutex);
344 boost::lock_guard<boost::mutex> lock(_mutex);
350 boost::lock_guard<boost::mutex> lock(_mutex);
356 boost::lock_guard<boost::mutex> lock(_mutex);
362 boost::lock_guard<boost::mutex> lock(_mutex);
368 boost::lock_guard<boost::mutex> lock(_mutex);
374 boost::lock_guard<boost::mutex> lock(_mutex);
459 typedef boost::shared_ptr<soft_regmap_accessor_t>
sptr;
499 boost::lock_guard<boost::mutex> lock(_mutex);
512 boost::lock_guard<boost::mutex> lock(_mutex);
525 boost::lock_guard<boost::mutex> lock(_mutex);
537 regmap_t::const_iterator iter = _regmap.find(name);
538 if (iter != _regmap.end()) {
539 return *(iter->second);
551 std::vector<std::string> temp;
552 BOOST_FOREACH (
const regmap_t::value_type& reg, _regmap) {
553 temp.push_back(_name +
"/" + reg.first);
568 const std::string& name,
571 boost::lock_guard<boost::mutex> lock(_mutex);
572 if (visible == PUBLIC) {
574 if (not _regmap.insert(regmap_t::value_type(name, ®)).second) {
576 "cannot add two registers with the same name to regmap: " + name);
579 _reglist.push_back(®);
583 typedef boost::unordered_map<std::string, soft_register_base*> regmap_t;
584 typedef std::list<soft_register_base*> reglist_t;
586 const std::string _name;
602 typedef boost::shared_ptr<soft_regmap_db_t>
sptr;
627 boost::lock_guard<boost::mutex> lock(_mutex);
628 _regmaps.push_back(®map);
636 boost::lock_guard<boost::mutex> lock(_mutex);
640 _regmap_dbs.push_back(&db);
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);
663 if ((tokens.size() > 2 && tokens.front() == _name) ||
664 (tokens.size() > 1 && _name ==
"")) {
667 if (tokens.size() == 2) {
669 if (regmap->
get_name() == tokens.front()) {
670 return regmap->
lookup(tokens.back());
674 }
else if (not _regmap_dbs
678 BOOST_FOREACH (
const std::string& node, tokens) {
679 newpath += (
"/" + node);
684 return db->
lookup(newpath.substr(1));
685 }
catch (std::exception&) {
699 std::vector<std::string> paths;
701 const std::vector<std::string>& regs = regmap->
enumerate();
702 paths.insert(paths.end(), regs.begin(), regs.end());
705 const std::vector<std::string>& regs = db->
enumerate();
706 paths.insert(paths.end(), regs.begin(), regs.end());
712 typedef std::list<soft_regmap_accessor_t*> db_t;
714 const std::string _name;
Definition: soft_register.hpp:105
virtual bool is_writable()=0
static UHD_INLINE soft_reg_t & cast(soft_register_base ®)
Definition: soft_register.hpp:120
virtual void initialize(wb_iface &iface, bool sync=false)=0
virtual bool is_readable()=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 ®map)
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 ®, 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