15#include <unordered_map> 
   16#include <boost/thread/locks.hpp> 
   17#include <boost/thread/mutex.hpp> 
   18#include <boost/tokenizer.hpp> 
   39#define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift) \ 
   40    static const uhd::soft_reg_field_t name = (((shift & 0xFF) << 8) | (width & 0xFF)) 
   50    return __builtin_expect(expr, 
true);
 
   60    return __builtin_expect(expr, 
false);
 
   75namespace soft_reg_field {
 
   78    return (field & 0xFF);
 
   83    return ((field >> 8) & 0xFF);
 
   86template <
typename data_t>
 
   89    constexpr data_t ONE      = 
static_cast<data_t
>(1);
 
   90    constexpr data_t ALL_ONES = ~static_cast<data_t>(0);
 
   95        return ((ONE << 
width(field)) - ONE) << 
shift(field);
 
   97        return ALL_ONES << 
shift(field);
 
  117    template <
typename soft_reg_t>
 
  120        soft_reg_t* ptr = 
dynamic_cast<soft_reg_t*
>(®);
 
  136template <
typename reg_data_t, 
bool readable, 
bool writable>
 
  140    typedef std::shared_ptr<soft_register_t<reg_data_t, readable, writable>> 
sptr;
 
  165        : _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)
 
  179        if (sync && writable)
 
  181        if (sync && readable)
 
  192        _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field))
 
  194                           & soft_reg_field::mask<reg_data_t>(field));
 
  203        return (_soft_copy & soft_reg_field::mask<reg_data_t>(field))
 
  212        if (writable && _iface) {
 
  216            if (_flush_mode == 
ALWAYS_FLUSH || _soft_copy.is_dirty()) {
 
  217                if (get_bitwidth() <= 32) {
 
  218                    _iface->poke32(_wr_addr, 
static_cast<uint32_t
>(_soft_copy));
 
  219                } 
else if (get_bitwidth() <= 64) {
 
  220                    _iface->poke64(_wr_addr, 
static_cast<uint64_t
>(_soft_copy));
 
  223                        "soft_register only supports up to 64 bits.");
 
  225                _soft_copy.mark_clean();
 
  229                "soft_register is not writable or uninitialized.");
 
  238        if (readable && _iface) {
 
  239            if (get_bitwidth() <= 32) {
 
  240                _soft_copy = 
static_cast<reg_data_t
>(_iface->peek32(_rd_addr));
 
  241            } 
else if (get_bitwidth() <= 64) {
 
  242                _soft_copy = 
static_cast<reg_data_t
>(_iface->peek64(_rd_addr));
 
  245                    "soft_register only supports up to 64 bits.");
 
  247            _soft_copy.mark_clean();
 
  250                "soft_register is not readable or uninitialized.");
 
  277        static const size_t BITS_IN_BYTE = 8;
 
  278        return sizeof(reg_data_t) * BITS_IN_BYTE;
 
  309template <
typename reg_data_t, 
bool readable, 
bool writable>
 
  314    typedef std::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable>> 
sptr;
 
  319        : 
soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode)
 
  326        : 
soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()
 
  332        boost::lock_guard<boost::mutex> lock(_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);
 
  446    typedef std::shared_ptr<soft_regmap_accessor_t> 
sptr;
 
  486        boost::lock_guard<boost::mutex> lock(_mutex);
 
  488            reg->initialize(iface, sync);
 
  499        boost::lock_guard<boost::mutex> lock(_mutex);
 
  512        boost::lock_guard<boost::mutex> lock(_mutex);
 
  524        regmap_t::const_iterator iter = _regmap.find(name);
 
  525        if (iter != _regmap.end()) {
 
  526            return *(iter->second);
 
  538        std::vector<std::string> temp;
 
  539        for (
const regmap_t::value_type& reg : _regmap) {
 
  540            temp.push_back(_name + 
"/" + reg.first);
 
  555        const std::string& name,
 
  558        boost::lock_guard<boost::mutex> lock(_mutex);
 
  559        if (visible == PUBLIC) {
 
  561            if (not _regmap.insert(regmap_t::value_type(name, ®)).second) {
 
  563                    "cannot add two registers with the same name to regmap: " + name);
 
  566        _reglist.push_back(®);
 
  570    typedef std::unordered_map<std::string, soft_register_base*> regmap_t;
 
  571    typedef std::list<soft_register_base*> reglist_t;
 
  573    const std::string _name;
 
  589    typedef std::shared_ptr<soft_regmap_db_t> 
sptr;
 
  614        boost::lock_guard<boost::mutex> lock(_mutex);
 
  615        _regmaps.push_back(®map);
 
  623        boost::lock_guard<boost::mutex> lock(_mutex);
 
  627            _regmap_dbs.push_back(&db);
 
  644        std::list<std::string> tokens;
 
  645        for (
const std::string& node : boost::tokenizer<boost::char_separator<char>>(
 
  646                 path, boost::char_separator<char>(
"/"))) {
 
  647            tokens.push_back(node);
 
  649        if ((tokens.size() > 2 && tokens.front() == _name) || 
 
  650            (tokens.size() > 1 && _name.empty())) { 
 
  653            if (tokens.size() == 2) { 
 
  655                    if (regmap->get_name() == tokens.front()) {
 
  656                        return regmap->lookup(tokens.back());
 
  660            } 
else if (not _regmap_dbs
 
  664                for (
const std::string& node : tokens) {
 
  665                    newpath += (
"/" + node);
 
  670                        return db->lookup(newpath.substr(1));
 
  671                    } 
catch (std::exception&) {
 
  685        std::vector<std::string> paths;
 
  687            const std::vector<std::string>& regs = regmap->enumerate();
 
  688            paths.insert(paths.end(), regs.begin(), regs.end());
 
  691            const std::vector<std::string>& regs = db->enumerate();
 
  692            paths.insert(paths.end(), regs.begin(), regs.end());
 
  698    typedef std::list<soft_regmap_accessor_t*> db_t;
 
  700    const std::string _name;
 
Definition: soft_register.hpp:103
 
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 ®)
Definition: soft_register.hpp:118
 
virtual bool is_readable()=0
 
virtual size_t get_bitwidth()=0
 
virtual ~soft_register_base()
Definition: soft_register.hpp:105
 
Definition: soft_register.hpp:312
 
soft_register_sync_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:324
 
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:316
 
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:336
 
UHD_INLINE void refresh()
Definition: soft_register.hpp:354
 
UHD_INLINE void flush()
Definition: soft_register.hpp:348
 
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:360
 
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:366
 
UHD_INLINE void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:330
 
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:342
 
std::shared_ptr< soft_register_sync_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:314
 
Definition: soft_register.hpp:138
 
soft_register_t(wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode=ALWAYS_FLUSH)
Definition: soft_register.hpp:163
 
UHD_INLINE void write(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:257
 
UHD_INLINE void refresh() override
Definition: soft_register.hpp:236
 
UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value)
Definition: soft_register.hpp:190
 
UHD_INLINE void flush() override
Definition: soft_register.hpp:210
 
UHD_INLINE size_t get_bitwidth() override
Definition: soft_register.hpp:275
 
UHD_INLINE bool is_writable() override
Definition: soft_register.hpp:292
 
UHD_INLINE reg_data_t read(const soft_reg_field_t field)
Definition: soft_register.hpp:266
 
UHD_INLINE reg_data_t get(const soft_reg_field_t field)
Definition: soft_register.hpp:201
 
std::shared_ptr< soft_register_t< reg_data_t, readable, writable > > sptr
Definition: soft_register.hpp:140
 
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:148
 
UHD_INLINE bool is_readable() override
Definition: soft_register.hpp:284
 
UHD_INLINE void initialize(wb_iface &iface, bool sync=false) override
Definition: soft_register.hpp:174
 
Definition: soft_register.hpp:444
 
virtual ~soft_regmap_accessor_t()
Definition: soft_register.hpp:448
 
std::shared_ptr< soft_regmap_accessor_t > sptr
Definition: soft_register.hpp:446
 
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:587
 
soft_register_base & lookup(const std::string &path) const override
Definition: soft_register.hpp:641
 
void add(soft_regmap_t ®map)
Definition: soft_register.hpp:612
 
std::vector< std::string > enumerate() const override
Definition: soft_register.hpp:683
 
std::shared_ptr< soft_regmap_db_t > sptr
Definition: soft_register.hpp:589
 
soft_regmap_db_t(const std::string &name)
Definition: soft_register.hpp:599
 
void add(soft_regmap_db_t &db)
Definition: soft_register.hpp:621
 
const std::string & get_name() const override
Definition: soft_register.hpp:604
 
soft_regmap_db_t()
Definition: soft_register.hpp:594
 
Definition: soft_register.hpp:465
 
void initialize(wb_iface &iface, bool sync=false)
Definition: soft_register.hpp:484
 
UHD_INLINE const std::string & get_name() const override
Definition: soft_register.hpp:473
 
std::vector< std::string > enumerate() const override
Definition: soft_register.hpp:536
 
soft_regmap_t(const std::string &name)
Definition: soft_register.hpp:467
 
~soft_regmap_t() override
Definition: soft_register.hpp:468
 
soft_register_base & lookup(const std::string &name) const override
Definition: soft_register.hpp:522
 
void flush()
Definition: soft_register.hpp:497
 
visibility_t
Definition: soft_register.hpp:546
 
@ PUBLIC
Definition: soft_register.hpp:547
 
UHD_INLINE void add_to_map(soft_register_base ®, const std::string &name, const visibility_t visible=PRIVATE)
Definition: soft_register.hpp:554
 
void refresh()
Definition: soft_register.hpp:510
 
Definition: wb_iface.hpp:18
 
uint32_t wb_addr_type
Definition: wb_iface.hpp:21
 
#define UHD_INLINE
Definition: config.h:55
 
#define UHD_API
Definition: config.h:70
 
UHD_INLINE data_t mask(const soft_reg_field_t field)
Definition: soft_register.hpp:87
 
UHD_INLINE size_t shift(const soft_reg_field_t field)
Definition: soft_register.hpp:81
 
UHD_INLINE size_t width(const soft_reg_field_t field)
Definition: soft_register.hpp:76
 
Definition: build_info.hpp:12
 
UHD_INLINE bool likely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:47
 
soft_register_t< uint64_t, false, true > soft_reg64_wo_t
Definition: soft_register.hpp:396
 
soft_register_sync_t< uint64_t, true, false > soft_reg64_ro_sync_t
Definition: soft_register.hpp:400
 
UHD_INLINE bool unlikely(bool expr)
hint for the branch prediction
Definition: soft_register.hpp:57
 
soft_register_sync_t< uint32_t, true, false > soft_reg32_ro_sync_t
Definition: soft_register.hpp:393
 
boost::noncopyable noncopyable
Definition: noncopyable.hpp:45
 
uint32_t soft_reg_field_t
Definition: soft_register.hpp:73
 
soft_register_t< uint32_t, true, false > soft_reg32_ro_t
Definition: soft_register.hpp:390
 
soft_register_t< uint32_t, true, true > soft_reg32_rw_t
Definition: soft_register.hpp:391
 
soft_register_sync_t< uint32_t, true, true > soft_reg32_rw_sync_t
Definition: soft_register.hpp:394
 
soft_register_t< uint64_t, true, false > soft_reg64_ro_t
Definition: soft_register.hpp:397
 
soft_register_sync_t< uint64_t, true, true > soft_reg64_rw_sync_t
Definition: soft_register.hpp:401
 
soft_register_sync_t< uint32_t, false, true > soft_reg32_wo_sync_t
Definition: soft_register.hpp:392
 
soft_reg_flush_mode_t
Definition: soft_register.hpp:129
 
@ OPTIMIZED_FLUSH
Definition: soft_register.hpp:129
 
@ ALWAYS_FLUSH
Definition: soft_register.hpp:129
 
soft_register_t< uint64_t, true, true > soft_reg64_rw_t
Definition: soft_register.hpp:398
 
soft_register_t< uint32_t, false, true > soft_reg32_wo_t
Definition: soft_register.hpp:389
 
soft_register_sync_t< uint64_t, false, true > soft_reg64_wo_sync_t
Definition: soft_register.hpp:399
 
#define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift)
Definition: soft_register.hpp:39
 
Definition: exception.hpp:49
 
Definition: exception.hpp:158
 
Definition: exception.hpp:133
 
Definition: exception.hpp:97