8 #ifndef INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP 9 #define INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP 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> 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>
UHD_INLINE data_t
mask(
const soft_reg_field_t field)
90 constexpr data_t ONE =
static_cast<data_t
>(1);
91 constexpr data_t ALL_ONES = ~static_cast<data_t>(0);
96 return ((ONE <<
width(field)) - ONE) <<
shift(field);
98 return ALL_ONES <<
shift(field);
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;
118 template <
typename soft_reg_t>
121 soft_reg_t* ptr =
dynamic_cast<soft_reg_t*
>(®);
137 template <
typename reg_data_t,
bool readable,
bool writable>
141 typedef boost::shared_ptr<soft_register_t<reg_data_t, readable, writable> >
sptr;
166 : _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)
180 if (sync && writable)
182 if (sync && readable)
191 UHD_INLINE void set(
const soft_reg_field_t field,
const reg_data_t value)
193 _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field))
195 & soft_reg_field::mask<reg_data_t>(field));
204 return (_soft_copy & soft_reg_field::mask<reg_data_t>(field))
213 if (writable && _iface) {
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));
226 "soft_register only supports up to 64 bits.");
228 _soft_copy.mark_clean();
232 "soft_register is not writable or uninitialized.");
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));
250 "soft_register only supports up to 64 bits.");
252 _soft_copy.mark_clean();
255 "soft_register is not readable or uninitialized.");
282 static const size_t BITS_IN_BYTE = 8;
283 return sizeof(reg_data_t) * BITS_IN_BYTE;
314 template <
typename reg_data_t,
bool readable,
bool writable>
319 typedef boost::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable> >
sptr;
324 :
soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode)
331 :
soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()
337 boost::lock_guard<boost::mutex> lock(_mutex);
341 UHD_INLINE void set(
const soft_reg_field_t field,
const reg_data_t value)
343 boost::lock_guard<boost::mutex> lock(_mutex);
349 boost::lock_guard<boost::mutex> lock(_mutex);
355 boost::lock_guard<boost::mutex> lock(_mutex);
361 boost::lock_guard<boost::mutex> lock(_mutex);
367 boost::lock_guard<boost::mutex> lock(_mutex);
373 boost::lock_guard<boost::mutex> lock(_mutex);
458 typedef boost::shared_ptr<soft_regmap_accessor_t>
sptr;
462 virtual std::vector<std::string> enumerate()
const = 0;
463 virtual const std::string& get_name()
const = 0;
498 boost::lock_guard<boost::mutex> lock(_mutex);
511 boost::lock_guard<boost::mutex> lock(_mutex);
524 boost::lock_guard<boost::mutex> lock(_mutex);
536 regmap_t::const_iterator iter = _regmap.find(name);
537 if (iter != _regmap.end()) {
538 return *(iter->second);
550 std::vector<std::string> temp;
551 BOOST_FOREACH (
const regmap_t::value_type& reg, _regmap) {
552 temp.push_back(_name +
"/" + reg.first);
567 const std::string& name,
570 boost::lock_guard<boost::mutex> lock(_mutex);
571 if (visible == PUBLIC) {
573 if (not _regmap.insert(regmap_t::value_type(name, ®)).second) {
575 "cannot add two registers with the same name to regmap: " + name);
578 _reglist.push_back(®);
582 typedef boost::unordered_map<std::string, soft_register_base*> regmap_t;
583 typedef std::list<soft_register_base*> reglist_t;
585 const std::string _name;
601 typedef boost::shared_ptr<soft_regmap_db_t>
sptr;
626 boost::lock_guard<boost::mutex> lock(_mutex);
627 _regmaps.push_back(®map);
635 boost::lock_guard<boost::mutex> lock(_mutex);
639 _regmap_dbs.push_back(&db);
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);
662 if ((tokens.size() > 2 && tokens.front() == _name) ||
663 (tokens.size() > 1 && _name ==
"")) {
666 if (tokens.size() == 2) {
668 if (regmap->
get_name() == tokens.front()) {
669 return regmap->
lookup(tokens.back());
673 }
else if (not _regmap_dbs
677 BOOST_FOREACH (
const std::string& node, tokens) {
678 newpath += (
"/" + node);
683 return db->
lookup(newpath.substr(1));
684 }
catch (std::exception&) {
698 std::vector<std::string> paths;
700 const std::vector<std::string>& regs = regmap->
enumerate();
701 paths.insert(paths.end(), regs.begin(), regs.end());
704 const std::vector<std::string>& regs = db->
enumerate();
705 paths.insert(paths.end(), regs.begin(), regs.end());
711 typedef std::list<soft_regmap_accessor_t*> db_t;
713 const std::string _name;
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
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
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 ®map)
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 ®, 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 ®)
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