14 #include <unordered_map> 15 #include <boost/tokenizer.hpp> 38 #define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift) \ 39 static const uhd::soft_reg_field_t name = (((shift & 0xFF) << 8) | (width & 0xFF)) 49 return __builtin_expect(expr,
true);
59 return __builtin_expect(expr,
false);
74 namespace soft_reg_field {
77 return (field & 0xFF);
82 return ((field >> 8) & 0xFF);
85 template <
typename data_t>
88 constexpr data_t ONE =
static_cast<data_t
>(1);
89 constexpr data_t ALL_ONES = ~static_cast<data_t>(0);
94 return ((ONE <<
width(field)) - ONE) <<
shift(field);
96 return ALL_ONES <<
shift(field);
106 virtual void initialize(
wb_iface& iface,
bool sync =
false) = 0;
107 virtual void flush() = 0;
108 virtual void refresh() = 0;
109 virtual size_t get_bitwidth() = 0;
110 virtual bool is_readable() = 0;
111 virtual bool is_writable() = 0;
116 template <
typename soft_reg_t>
119 soft_reg_t* ptr =
dynamic_cast<soft_reg_t*
>(®);
135 template <
typename reg_data_t,
bool readable,
bool writable>
139 typedef std::shared_ptr<soft_register_t<reg_data_t, readable, writable>>
sptr;
164 : _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)
178 if (sync && writable)
180 if (sync && readable)
189 UHD_INLINE void set(
const soft_reg_field_t field,
const reg_data_t value)
191 _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field))
193 & soft_reg_field::mask<reg_data_t>(field));
202 return (_soft_copy & soft_reg_field::mask<reg_data_t>(field))
211 if (writable && _iface) {
215 if (_flush_mode == ALWAYS_FLUSH || _soft_copy.is_dirty()) {
216 if (get_bitwidth() <= 32) {
217 _iface->poke32(_wr_addr, static_cast<uint32_t>(_soft_copy));
218 }
else if (get_bitwidth() <= 64) {
219 _iface->poke64(_wr_addr, static_cast<uint64_t>(_soft_copy));
222 "soft_register only supports up to 64 bits.");
224 _soft_copy.mark_clean();
228 "soft_register is not writable or uninitialized.");
237 if (readable && _iface) {
238 if (get_bitwidth() <= 32) {
239 _soft_copy =
static_cast<reg_data_t
>(_iface->peek32(_rd_addr));
240 }
else if (get_bitwidth() <= 64) {
241 _soft_copy =
static_cast<reg_data_t
>(_iface->peek64(_rd_addr));
244 "soft_register only supports up to 64 bits.");
246 _soft_copy.mark_clean();
249 "soft_register is not readable or uninitialized.");
276 static const size_t BITS_IN_BYTE = 8;
277 return sizeof(reg_data_t) * BITS_IN_BYTE;
308 template <
typename reg_data_t,
bool readable,
bool writable>
313 typedef std::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable>>
sptr;
318 :
soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode)
325 :
soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()
331 std::lock_guard<std::mutex> lock(_mutex);
335 UHD_INLINE void set(
const soft_reg_field_t field,
const reg_data_t value)
337 std::lock_guard<std::mutex> lock(_mutex);
343 std::lock_guard<std::mutex> lock(_mutex);
349 std::lock_guard<std::mutex> lock(_mutex);
355 std::lock_guard<std::mutex> lock(_mutex);
361 std::lock_guard<std::mutex> lock(_mutex);
367 std::lock_guard<std::mutex> lock(_mutex);
445 typedef std::shared_ptr<soft_regmap_accessor_t>
sptr;
449 virtual std::vector<std::string> enumerate()
const = 0;
450 virtual const std::string& get_name()
const = 0;
485 std::lock_guard<std::mutex> lock(_mutex);
487 reg->initialize(iface, sync);
498 std::lock_guard<std::mutex> lock(_mutex);
511 std::lock_guard<std::mutex> lock(_mutex);
523 regmap_t::const_iterator iter = _regmap.find(name);
524 if (iter != _regmap.end()) {
525 return *(iter->second);
537 std::vector<std::string> temp;
538 for (
const regmap_t::value_type& reg : _regmap) {
539 temp.push_back(_name +
"/" + reg.first);
554 const std::string& name,
557 std::lock_guard<std::mutex> lock(_mutex);
558 if (visible == PUBLIC) {
560 if (not _regmap.insert(regmap_t::value_type(name, ®)).second) {
562 "cannot add two registers with the same name to regmap: " + name);
565 _reglist.push_back(®);
569 typedef std::unordered_map<std::string, soft_register_base*> regmap_t;
570 typedef std::list<soft_register_base*> reglist_t;
572 const std::string _name;
588 typedef std::shared_ptr<soft_regmap_db_t>
sptr;
613 std::lock_guard<std::mutex> lock(_mutex);
614 _regmaps.push_back(®map);
622 std::lock_guard<std::mutex> lock(_mutex);
626 _regmap_dbs.push_back(&db);
643 std::list<std::string> tokens;
644 for (
const std::string& node : boost::tokenizer<boost::char_separator<char>>(
645 path, boost::char_separator<char>(
"/"))) {
646 tokens.push_back(node);
648 if ((tokens.size() > 2 && tokens.front() == _name) ||
649 (tokens.size() > 1 && _name.empty())) {
652 if (tokens.size() == 2) {
654 if (regmap->get_name() == tokens.front()) {
655 return regmap->lookup(tokens.back());
659 }
else if (not _regmap_dbs
663 for (
const std::string& node : tokens) {
664 newpath += (
"/" + node);
669 return db->lookup(newpath.substr(1));
670 }
catch (std::exception&) {
684 std::vector<std::string> paths;
686 const std::vector<std::string>& regs = regmap->enumerate();
687 paths.insert(paths.end(), regs.begin(), regs.end());
690 const std::vector<std::string>& regs = db->enumerate();
691 paths.insert(paths.end(), regs.begin(), regs.end());
697 typedef std::list<soft_regmap_accessor_t*> db_t;
699 const std::string _name;
void refresh()
Definition: soft_register.hpp:509
uint32_t soft_reg_field_t
Definition: soft_register.hpp:72
UHD_INLINE bool is_writable() override
Definition: soft_register.hpp:291
std::shared_ptr< soft_register_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:139
Definition: soft_register.hpp:128
soft_reg_flush_mode_t
Definition: soft_register.hpp:128
UHD_INLINE void initialize(wb_iface &iface, bool sync=false) override
Definition: soft_register.hpp:173
Definition: soft_register.hpp:309
Definition: exception.hpp:156
soft_regmap_t(const std::string &name)
Definition: soft_register.hpp:466
UHD_INLINE bool unlikely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:56
std::vector< std::string > enumerate() const override
Definition: soft_register.hpp:535
soft_register_t< uint64_t, false, true > soft_reg64_wo_t
Definition: soft_register.hpp:395
soft_register_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:162
boost::noncopyable noncopyable
Definition: noncopyable.hpp:45
#define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift)
Definition: soft_register.hpp:38
soft_register_t< uint32_t, true, false > soft_reg32_ro_t
Definition: soft_register.hpp:389
UHD_INLINE const std::string & get_name() const override
Definition: soft_register.hpp:472
soft_register_sync_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:323
soft_register_sync_t< uint64_t, true, true > soft_reg64_rw_sync_t
Definition: soft_register.hpp:400
Definition: exception.hpp:131
Definition: soft_register.hpp:585
UHD_INLINE void flush() override
Definition: soft_register.hpp:209
soft_register_sync_t< uint32_t, false, true > soft_reg32_wo_sync_t
Definition: soft_register.hpp:391
soft_register_t< uint32_t, false, true > soft_reg32_wo_t
Definition: soft_register.hpp:388
UHD_INLINE size_t width(const soft_reg_field_t field)
Definition: soft_register.hpp:75
Definition: soft_register.hpp:546
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:189
soft_regmap_db_t(const std::string &name)
Definition: soft_register.hpp:598
virtual ~soft_regmap_accessor_t()
Definition: soft_register.hpp:447
Definition: soft_register.hpp:136
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:200
Definition: build_info.hpp:12
soft_regmap_db_t()
Definition: soft_register.hpp:593
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:359
virtual ~soft_register_base()
Definition: soft_register.hpp:104
void flush()
Definition: soft_register.hpp:496
~soft_regmap_t() override
Definition: soft_register.hpp:467
std::shared_ptr< soft_regmap_db_t > sptr
Definition: soft_register.hpp:588
visibility_t
Definition: soft_register.hpp:545
const std::string & get_name() const override
Definition: soft_register.hpp:603
void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:483
soft_register_sync_t< uint64_t, true, false > soft_reg64_ro_sync_t
Definition: soft_register.hpp:399
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:315
Definition: soft_register.hpp:442
#define UHD_INLINE
Definition: config.h:65
UHD_INLINE void flush()
Definition: soft_register.hpp:347
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:265
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:147
soft_register_t< uint64_t, true, false > soft_reg64_ro_t
Definition: soft_register.hpp:396
Definition: soft_register.hpp:463
Definition: soft_register.hpp:101
soft_register_sync_t< uint32_t, true, false > soft_reg32_ro_sync_t
Definition: soft_register.hpp:392
std::vector< std::string > enumerate() const override
Definition: soft_register.hpp:682
Definition: exception.hpp:47
#define UHD_API
Definition: config.h:87
UHD_INLINE data_t mask(const soft_reg_field_t field)
Definition: soft_register.hpp:86
UHD_INLINE bool is_readable() override
Definition: soft_register.hpp:283
void add(soft_regmap_t ®map)
Definition: soft_register.hpp:611
soft_register_base & lookup(const std::string &name) const override
Definition: soft_register.hpp:521
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:365
UHD_INLINE void refresh()
Definition: soft_register.hpp:353
soft_register_t< uint64_t, true, true > soft_reg64_rw_t
Definition: soft_register.hpp:397
soft_register_base & lookup(const std::string &path) const override
Definition: soft_register.hpp:640
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:256
UHD_INLINE void refresh() override
Definition: soft_register.hpp:235
Definition: exception.hpp:95
void add(soft_regmap_db_t &db)
Definition: soft_register.hpp:620
std::shared_ptr< soft_regmap_accessor_t > sptr
Definition: soft_register.hpp:445
UHD_INLINE size_t get_bitwidth() override
Definition: soft_register.hpp:274
soft_register_sync_t< uint64_t, false, true > soft_reg64_wo_sync_t
Definition: soft_register.hpp:398
std::shared_ptr< soft_register_sync_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:313
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:329
UHD_INLINE bool likely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:46
soft_register_sync_t< uint32_t, true, true > soft_reg32_rw_sync_t
Definition: soft_register.hpp:393
UHD_INLINE void add_to_map(soft_register_base ®, const std::string &name, const visibility_t visible=PRIVATE)
Definition: soft_register.hpp:553
UHD_INLINE size_t shift(const soft_reg_field_t field)
Definition: soft_register.hpp:80
Definition: soft_register.hpp:128
uint32_t wb_addr_type
Definition: wb_iface.hpp:21
static UHD_INLINE soft_reg_t & cast(soft_register_base ®)
Definition: soft_register.hpp:117
Definition: wb_iface.hpp:17
soft_register_t< uint32_t, true, true > soft_reg32_rw_t
Definition: soft_register.hpp:390