3.5.1.19.1 Streaming Library
(Ask a Question)The streaming library includes the FIFO (first-in first-out) data structure along with its associated API functions. The library can be compiled in software to run on the host machine (e.g., x86). Each FIFO instance in software is implemented as a First Word Fall Through (FWFT) FIFO in hardware.
The FIFO library is provided as a C++ template class. The FIFO data type can be flexibly defined and specified as a template argument of the FIFO object. For example, the FIFO data type could be defined as a struct containing multiple integers:
struct AxisWord { ap_uint<64> data; ap_uint<8> keep; ap_uint<1> last; }; hls::FIFO<AxisWord> my_axi_stream_interface_fifo;
You can use the C++ streaming library by including the header file:
#include "hls/streaming.hpp"
Class Method | Description |
---|---|
FIFO<T> () | Create a new FIFO. |
FIFO<T> (unsigned depth) | Create a new FIFO with the specified depth. |
void write(T data) | Write data to the FIFO. |
T read() | Read an element from the FIFO. |
bool empty() | Returns 1 if the FIFO is empty. |
bool full() | Returns 1 if the FIFO is full. |
void setDepth(unsigned depth) | Set the FIFO’s depth. |
#include <hls/streaming.hpp> void write(hls::FIFO<unsigned> *my_fifo, unsigned data) { // write to the fifo my_fifo->write(data); } void read_write(hls::FIFO<unsigned> *my_fifo, hls::FIFO<unsigned> *out_fifo) { #pragma HLS function top // read from the fifo unsigned data = my_fifo->read(); out_fifo->write(data); } int main() { // declare a 32-bit wide fifo hls::FIFO<unsigned> my_fifo; // set the fifo's depth to 10 my_fifo.setDepth(10); // declare a 32-bit wide fifo with a depth of 10 hls::FIFO<unsigned> my_fifo_depth_10(10); write(&my_fifo, 10); read_write(&my_fifo, &my_fifo_depth_10); // check if my_fifo is empty - should be empty since we read from it in // read_write (is_empty = 1) bool is_empty = my_fifo.empty(); // check if my_fifo_depth_10 is empty - should not be empty since we write // to it in read_write (is_empty = 0) bool is_second_empty = my_fifo_depth_10.empty(); // We will use the fail variable to check for any failures. fail will become // 1 if is_empty != 1 and is_second_empty != 0 int fail = (is_empty == 1) ? ((is_second_empty == 0) ? 0 : 1) : 1; // If fail is 1, test will fail. return fail; }
As shown above, there are two ways of creating a FIFO (hls::FIFO<unsigned> my_fifo
and hls::FIFO<unsigned> my_fifo_depth_10(10)
). The width of the FIFO is determined based on the templated data type of the FIFO. For example, FIFO<unsigned> my_fifo
creates a FIFO that is 32 bits wide. The FIFO's data type can be any primitive type or arbitrary bitwidth types (ap_int/ap_uint/ap_fixpt/ap_ufixpt), or a struct of primitive/arbitrary bitwidth types (or nested structs of those types) but cannot be a pointer or an array (or a struct with a pointer/array). An array or a struct of FIFOs is supported.
The depth of the FIFO can be provided by the user as a constructor argument when the FIFO is declared, or it can also be set afterwards with the setDepth(unsigned depth)
function. If the depth is not provided by the user, SmartHLS uses a default FIFO depth of 2. The depth of a FIFO can also be set to 0, in which case SmartHLS will create direct ready/valid/data wire connections (without a FIFO) between the source and the sink.