diff options
| -rw-r--r-- | host/include/uhd/rfnoc/register_iface.hpp | 63 | ||||
| -rw-r--r-- | host/lib/rfnoc/ctrlport_endpoint.cpp | 15 | ||||
| -rw-r--r-- | host/tests/rfnoc_mock_reg_iface.hpp | 13 | 
3 files changed, 87 insertions, 4 deletions
| diff --git a/host/include/uhd/rfnoc/register_iface.hpp b/host/include/uhd/rfnoc/register_iface.hpp index 729aedbe6..a89d85717 100644 --- a/host/include/uhd/rfnoc/register_iface.hpp +++ b/host/include/uhd/rfnoc/register_iface.hpp @@ -58,6 +58,33 @@ public:          uhd::time_spec_t time = uhd::time_spec_t::ASAP,          bool ack              = false) = 0; +    /*! Write two consecutive 32-bit registers implemented in the NoC block from +     * one 64-bit value. +     * +     * Note: This is a convenience call, because all register pokes are 32-bits. +     * This will concatenate two pokes in a block poke, and then return the +     * combined result of the two pokes. +     * +     * \param addr The byte address of the lower 32-bit register to read from +     *             (truncated to 20 bits). +     * \param data New value of the register(s). +     * \param time The time at which the transaction should be executed. +     * +     * \throws op_failed if the transaction fails +     * \throws op_timeout if no response is received +     * \throws op_seqerr if a sequence error occurs +     */ +    void poke64(uint32_t addr, +        uint64_t data, +        time_spec_t time = uhd::time_spec_t::ASAP, +        bool ack         = false) +    { +        block_poke32(addr, +            {uint32_t(data & 0xFFFFFFFF), uint32_t((data >> 32) & 0xFFFFFFFF)}, +            time, +            ack); +    } +      /*! Write multiple 32-bit registers implemented in the NoC block.       *       * This method should be called when multiple writes need to happen that are @@ -110,7 +137,6 @@ public:       *       * \param addr The byte address of the register to read from (truncated to 20 bits).       * \param time The time at which the transaction should be executed. -     * \return data New value of this register.       *       * \throws op_failed if the transaction fails       * \throws op_timeout if no response is received @@ -118,6 +144,27 @@ public:       */      virtual uint32_t peek32(uint32_t addr, time_spec_t time = uhd::time_spec_t::ASAP) = 0; +    /*! Read two consecutive 32-bit registers implemented in the NoC block +     * and return them as one 64-bit value. +     * +     * Note: This is a convenience call, because all register peeks are 32-bits. +     * This will concatenate two peeks in a block peek, and then return the +     * combined result of the two peeks. +     * +     * \param addr The byte address of the lower 32-bit register to read from +     *             (truncated to 20 bits). +     * \param time The time at which the transaction should be executed. +     * +     * \throws op_failed if the transaction fails +     * \throws op_timeout if no response is received +     * \throws op_seqerr if a sequence error occurs +     */ +    uint64_t peek64(uint32_t addr, time_spec_t time = uhd::time_spec_t::ASAP) +    { +        const auto vals = block_peek32(addr, 2, time); +        return uint64_t(vals[0]) | (uint64_t(vals[1]) << 32); +    } +      /*! Read multiple 32-bit consecutive registers implemented in the NoC block.       *       * \param first_addr The byte address of the first register to read from @@ -216,6 +263,20 @@ public:       */      virtual void set_policy(const std::string& name, const uhd::device_addr_t& args) = 0; +    /*! Get the endpoint ID of the software counterpart of this register interface. +     *  This information is useful to send async messages to the host. +     * +     * \return The 16-bit endpoint ID +     */ +    virtual uint16_t get_src_epid() const = 0; + +    /*! Get the port number of the software counterpart of this register interface. +     *  This information is useful to send async messages to the host. +     * +     * \return The 10-bit port number +     */ +    virtual uint16_t get_port_num() const = 0; +  }; // class register_iface  }} /* namespace uhd::rfnoc */ diff --git a/host/lib/rfnoc/ctrlport_endpoint.cpp b/host/lib/rfnoc/ctrlport_endpoint.cpp index 93236940f..a618eaca2 100644 --- a/host/lib/rfnoc/ctrlport_endpoint.cpp +++ b/host/lib/rfnoc/ctrlport_endpoint.cpp @@ -263,7 +263,10 @@ public:                  UHD_LOG_ERROR(                      "CTRLEP", "Malformed async message request: Invalid opcode");              } else if (rx_ctrl.dst_port != _local_port) { -                UHD_LOG_ERROR("CTRLEP", "Malformed async message request: Invalid port"); +                UHD_LOG_ERROR("CTRLEP", +                    "Malformed async message request: Invalid port " +                        << rx_ctrl.dst_port << ", expected my local port " +                        << _local_port);              } else if (rx_ctrl.data_vtr.empty()) {                  UHD_LOG_ERROR(                      "CTRLEP", "Malformed async message request: Invalid num_data"); @@ -291,6 +294,16 @@ public:          }      } +    virtual uint16_t get_src_epid() const +    { +        return _my_epid; +    } + +    virtual uint16_t get_port_num() const +    { +        return _local_port; +    } +  private:      //! Returns the length of the control payload in 32-bit words      inline static size_t get_payload_size(const ctrl_payload& payload) diff --git a/host/tests/rfnoc_mock_reg_iface.hpp b/host/tests/rfnoc_mock_reg_iface.hpp index 3ceb95893..b43317237 100644 --- a/host/tests/rfnoc_mock_reg_iface.hpp +++ b/host/tests/rfnoc_mock_reg_iface.hpp @@ -106,6 +106,15 @@ public:              "Requested to set policy for " << name << " to " << args.to_string());      } +    uint16_t get_src_epid() const +    { +        return 0; +    } + +    uint16_t get_port_num() const +    { +        return 0; +    }      bool force_timeout = false; @@ -113,7 +122,8 @@ public:      std::unordered_map<uint32_t, uint32_t> write_memory;  protected: -    virtual void _poke_cb(uint32_t /*addr*/, uint32_t /*data*/, uhd::time_spec_t /*time*/, bool /*ack*/) +    virtual void _poke_cb( +        uint32_t /*addr*/, uint32_t /*data*/, uhd::time_spec_t /*time*/, bool /*ack*/)      {      }      virtual void _peek_cb(uint32_t /*addr*/, uhd::time_spec_t /*time*/) {} @@ -121,4 +131,3 @@ protected:  #endif /* INCLUDED_LIBUHD_TESTS_MOCK_REG_IFACE_HPP */ - | 
