diff options
author | mattprost <matt.prost@ni.com> | 2020-03-04 16:29:39 -0600 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-08-04 15:40:30 -0500 |
commit | ef16cea9bd951a83e8d2818f80d43c80db1beb96 (patch) | |
tree | fb4478e117f2f5fc82e01f80e84107cbf6fb6e54 /host/include | |
parent | 6d92a1828121ca4b57d496bbf522820f961244b9 (diff) | |
download | uhd-ef16cea9bd951a83e8d2818f80d43c80db1beb96.tar.gz uhd-ef16cea9bd951a83e8d2818f80d43c80db1beb96.tar.bz2 uhd-ef16cea9bd951a83e8d2818f80d43c80db1beb96.zip |
rfnoc: Add RFNoC replay block
Signed-off-by: mattprost <matt.prost@ni.com>
Diffstat (limited to 'host/include')
-rw-r--r-- | host/include/uhd/rfnoc/defaults.hpp | 3 | ||||
-rw-r--r-- | host/include/uhd/rfnoc/replay_block_control.hpp | 324 |
2 files changed, 326 insertions, 1 deletions
diff --git a/host/include/uhd/rfnoc/defaults.hpp b/host/include/uhd/rfnoc/defaults.hpp index 781beb696..f96dad8a0 100644 --- a/host/include/uhd/rfnoc/defaults.hpp +++ b/host/include/uhd/rfnoc/defaults.hpp @@ -82,10 +82,11 @@ static const noc_id_t FIR_FILTER_BLOCK = 0xF1120000; static const noc_id_t FOSPHOR_BLOCK = 0x666F0000; static const noc_id_t LOGPWR_BLOCK = 0x4C500000; static const noc_id_t MOVING_AVERAGE_BLOCK = 0xAAD20000; +static const noc_id_t RADIO_BLOCK = 0x12AD1000; +static const noc_id_t REPLAY_BLOCK = 0x4E91A000; static const noc_id_t SIGGEN_BLOCK = 0x51663110; static const noc_id_t SPLIT_STREAM_BLOCK = 0x57570000; static const noc_id_t SWITCHBOARD_BLOCK = 0xBE110000; -static const noc_id_t RADIO_BLOCK = 0x12AD1000; static const noc_id_t VECTOR_IIR_BLOCK = 0x11120000; static const noc_id_t WINDOW_BLOCK = 0xD0530000; diff --git a/host/include/uhd/rfnoc/replay_block_control.hpp b/host/include/uhd/rfnoc/replay_block_control.hpp new file mode 100644 index 000000000..a3f2ce90d --- /dev/null +++ b/host/include/uhd/rfnoc/replay_block_control.hpp @@ -0,0 +1,324 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#pragma once + +#include <uhd/config.hpp> +#include <uhd/rfnoc/noc_block_base.hpp> + +namespace uhd { namespace rfnoc { + +/*! Replay Block Control CLass + * + * The Replay block records data to memory and plays back data from memory. + * + * It is the responsibility of the user to manage the memory. Care must be taken to avoid + * unintentional overlaps in the memory across blocks and ports. Each port of the Replay + * block has access to the full memory space. This allows recording data on any input port + * of any Replay block and playback on any output port of any Replay block. The section of + * memory used by a record or play operation is controlled by setting the offset and size. + * + * For both record and playback, the offset and the size must be aligned to the memory's + * word size. For playback, the size must also be aligned to the size of an item. An item + * is a single unit of data as defined by the data type of a port. For record, the data + * type is automatically determined by the connection to the upstream block by using the + * "type" edge property for the corresponding input port. For playback, this is + * automatically determined by the connection to the downstream block by using the "type" + * edge property for the corresponding output port. These can be explicitly set by the + * user, if necessary. It is the user's responsibility to manage the types of the + * individual record and the playback ports. Methods to get the word size and item sizes + * are provided to help calculate proper alignment. + * + * One key configuration of playback is the packet size. Larger packet sizes provide for + * better throughput while smaller packet sizes provide for lower latency. By default, + * the "mtu" edge property of the output port is used to define the maximum packet size to + * achieve the best throughput to the downstream block without exceeding the supported + * packet size. The maximum packet size can be explicitly set in terms of bytes or + * number of items to allow users to tune the performance to suit their application. + */ +class UHD_API replay_block_control : public noc_block_base +{ +public: + RFNOC_DECLARE_BLOCK(replay_block_control) + + static const uint16_t MINOR_COMPAT; + static const uint16_t MAJOR_COMPAT; + + static const uint32_t REPLAY_ADDR_W; + static const uint32_t REPLAY_BLOCK_OFFSET; + + static const uint32_t REG_COMPAT_ADDR; + static const uint32_t REG_MEM_SIZE_ADDR; + static const uint32_t REG_REC_RESTART_ADDR; + static const uint32_t REG_REC_BASE_ADDR_LO_ADDR; + static const uint32_t REG_REC_BASE_ADDR_HI_ADDR; + static const uint32_t REG_REC_BUFFER_SIZE_LO_ADDR; + static const uint32_t REG_REC_BUFFER_SIZE_HI_ADDR; + static const uint32_t REG_REC_FULLNESS_LO_ADDR; + static const uint32_t REG_REC_FULLNESS_HI_ADDR; + static const uint32_t REG_PLAY_BASE_ADDR_LO_ADDR; + static const uint32_t REG_PLAY_BASE_ADDR_HI_ADDR; + static const uint32_t REG_PLAY_BUFFER_SIZE_LO_ADDR; + static const uint32_t REG_PLAY_BUFFER_SIZE_HI_ADDR; + static const uint32_t REG_PLAY_CMD_NUM_WORDS_LO_ADDR; + static const uint32_t REG_PLAY_CMD_NUM_WORDS_HI_ADDR; + static const uint32_t REG_PLAY_CMD_TIME_LO_ADDR; + static const uint32_t REG_PLAY_CMD_TIME_HI_ADDR; + static const uint32_t REG_PLAY_CMD_ADDR; + static const uint32_t REG_PLAY_WORDS_PER_PKT_ADDR; + static const uint32_t REG_PLAY_ITEM_SIZE_ADDR; + + static const uint32_t PLAY_CMD_STOP; + static const uint32_t PLAY_CMD_FINITE; + static const uint32_t PLAY_CMD_CONTINUOUS; + + /************************************************************************** + * Replay Control API calls + *************************************************************************/ + /*! Record + * + * Begin recording. The offset sets the starting location in memory and the size + * limits the length of the recording. The flow of data is controlled by upstream + * RFNoC blocks. + * + * \param offset Memory offset where to start recording the data. This value + * must be aligned to the memory word size. Use get_word_size() to get the + * size of the memory word. + * \param size Size limit, in bytes. This value must be aligned to the memory + * word size and the item size. Use get_word_size() to get the size of the + * memory word and get_item_size() to get the item size. A value of 0 means + * to use all available space. + * \param port Which input port of the replay block to use + */ + virtual void record( + const uint64_t offset, const uint64_t size, const size_t port = 0) = 0; + + /*! Restarts recording from the record offset + * + * \param port Which input port of the replay block to use + */ + virtual void record_restart(const size_t port = 0) = 0; + + /*! Play + * + * Play back data. The offset and size define what data is played back on an output + * port. The data can be played once or repeated continuously until a stop command is + * issued. If a time_spec is supplied, it will be placed in the header of the first + * packet. Typically, this is used to tell a downstream Radio block when to start + * transmitting the data. If the data type on the output port is not defined, this + * function will throw an error. + * + * \param offset Memory offset of the data to be played. This value must be + * aligned to the size of the word in memory. Use get_word_size() to get the + * memory word size. + * \param size Size of data to play back. This value must be aligned to the + * size of the memory word and item size. Use get_word_size() to get the + * memory word size and get_output_item_size() to get the item size. + * \param port Which output port of the replay block to use + * \param time_spec Set the time for the first item. Any non-zero value is used to + * set the time in the header of the first packet. Most commonly, this is used to + * set the start time of a transmission. + * \param repeat Determines whether the data should be played repeatedly or + * just once. If set to true, stop() must be called to stop the play back. + */ + virtual void play(const uint64_t offset, + const uint64_t size, + const size_t port = 0, + const uhd::time_spec_t time_spec = uhd::time_spec_t(0.0), + const bool repeat = false) = 0; + + /*! Stops playback + * + * Halts any currently executing play commands and cancels any other play commands + * that are waiting to be executed for that output port. + * + * \param port Which output port of the replay block to use + */ + virtual void stop(const size_t port = 0) = 0; + + /*! Get the size of the memory + * + * Returns the size of the shared memory space. Any record or playback buffers must + * be configured in this memory space. + * + * \returns the size of the shared Replay memory + */ + virtual uint64_t get_mem_size() const = 0; + + /*! Get the size of a memory word + * + * \returns the size of a memory word + */ + virtual uint64_t get_word_size() const = 0; + + /************************************************************************** + * Record State API calls + *************************************************************************/ + /*! Get the starting offset of the current record buffer + * + * \param port Which input port of the replay block to use + * \returns starting offset of the record buffer + */ + virtual uint64_t get_record_offset(const size_t port = 0) const = 0; + + /*! Get the current size of the record space + * + * \param port Which input port of the replay block to use + * \returns size of the record buffer + */ + virtual uint64_t get_record_size(const size_t port = 0) const = 0; + + /*! Get the fullness of the current record buffer + * + * Returns the number of bytes that have been recorded in the record buffer. A record + * restart will reset this number back to 0. + * + * \param port Which input port of the replay block to use + * \returns fullness of the record buffer + */ + virtual uint64_t get_record_fullness(const size_t port = 0) = 0; + + /*! Get the current record data type + * + * \param port Which input port of the replay block to use + * \returns the current record data type + */ + virtual io_type_t get_record_type(const size_t port = 0) const = 0; + + /*! Get the current record item size + * + * \param port Which input port of the replay block to use + * \returns the size of an item in the current record buffer + */ + virtual size_t get_record_item_size(const size_t port = 0) const = 0; + + /************************************************************************** + * Playback State API calls + *************************************************************************/ + /*! Get the offset of the current playback buffer + * + * \param port Which output port of the replay block to use + * \returns the offset of the current playback buffer + */ + virtual uint64_t get_play_offset(const size_t port = 0) const = 0; + + /*! Get the current size of the playback space + * + * \param port Which output port of the replay block to use + * \returns size of the playback buffer + */ + virtual uint64_t get_play_size(const size_t port = 0) const = 0; + + /*! Get the maximum number of items in a packet + * + * \param port Which output port of the replay block to use + * \returns the maximum number of items in a packet + */ + virtual uint32_t get_max_items_per_packet(const size_t port = 0) const = 0; + + /*! Get the maximum size of a packet + * + * Returns the maximum size of a packet, inclusive of headers and payload. + * + * \param port Which output port of the replay block to use + * \returns the maximum size of a packet + */ + virtual uint32_t get_max_packet_size(const size_t port = 0) const = 0; + + /*! Get the current play data type + * + * \param port Which output port of the replay block to use + * \returns the current play data type + */ + virtual io_type_t get_play_type(const size_t port = 0) const = 0; + + /*! Get the current play item size + * + * \param port Which output port of the replay block to use + * \returns the size of an item in the current play buffer + */ + virtual size_t get_play_item_size(const size_t port = 0) const = 0; + + /************************************************************************** + * Advanced Record Control API calls + *************************************************************************/ + /*! Explicitly set the current record data type + * + * Sets the data type for items in the current record buffer for the given input port. + * + * \param type The data type + * \param port Which input port of the replay block to use + */ + virtual void set_record_type(const io_type_t type, const size_t port = 0) = 0; + + /************************************************************************** + * Advanced Playback Control API calls + *************************************************************************/ + /*! Configure the offsets and size of the playback buffer region + * + * Specifies a buffer area in the memory for playback. In order to begin + * playback on this region, a stream command must be issued. + * + * \param offset Memory offset of the data to be played. This value must be + * aligned to the size of the word in memory. Use get_word_size() to get the + * memory word size. + * \param size Size of data to play back. This value must be aligned to the + * size of the memory word and item size. Use get_word_size() to get the + * memory word size and get_output_item_size() to get the item size. + * \param port Which output port of the replay block to use + */ + virtual void config_play( + const uint64_t offset, const uint64_t size, const size_t port = 0) = 0; + + /*! Explicitly set the current play data type + * + * Sets the data type for items in the current play buffer for the given output port. + * + * \param type The data type + * \param port Which output port of the replay block to use + */ + virtual void set_play_type(const io_type_t type, const size_t port = 0) = 0; + + /*! Set the maximum number of items in a packet + * + * Sets the maximum number of items that can be in a packet's payload. An actual + * packet may be smaller in order to coerce to mtu values, or to align with memory + * word size. + * + * \param ipp Number of items per packet + * \param port Which output port of the replay block to use + */ + virtual void set_max_items_per_packet(const uint32_t ipp, const size_t port = 0) = 0; + + /*! Set the maximum size of a packet + * + * Sets the maximum packet size, inclusive of headers and payload. + * + * \param size The size of the packet + * \param port Which output port of the replay block to use + */ + virtual void set_max_packet_size(const uint32_t size, const size_t port = 0) = 0; + + /*! Issue a stream command to the replay block + * + * Issue stream commands to start or stop playback from the configured playback + * buffer. Supports + * STREAM_MODE_START_CONTINUOUS to start continuous repeating playback, + * STREAM_MODE_START_NUM_SAMPS_AND_DONE to play the given number of samples once, and + * STREAM_MODE_STOP_CONTINUOUS to stop all playback immediately. + * If a time_spec is supplied, it is placed in the header of the first packet produced + * for that command. Commands are queued and executed in order. A + * STREAM_MODE_STOP_CONTINUOUS command will halt all playback and purge all commands + * in the queue for a given output port. + * + * \param stream_cmd The command to execute + * \param port Which output port of the replay block to use + */ + virtual void issue_stream_cmd( + const uhd::stream_cmd_t& stream_cmd, const size_t port = 0) = 0; +}; + +}} /* namespace uhd::rfnoc */ |