# hls::stream Class ## Introduction This class is an API compatible class with Xilinx provides **hls::stream** class in Vivado HLS. In the **vsi::runtime** implementation the **hls::stream** is thread safe . This document describes the **vsi::runtime** implementation of the hls::stream class, please refer to the Section “Using HLS Streams” in the “Vivado High Level Synthesis : User Guide (UG902)” for details on the hardware implementation of this class. Care has been taken to match the hardware behavior. ## Class instance. The hls::stream is a template class and requires a “type” to be instantiated. The data in the hls::stream class can only be accessed sequentially; the data is stored and retrieved using the First In First Out method. The following example shows an instance of hls::stream. `typedef unsigned int uint; hls::stream uistrm;` ## Public APIs. ### void hls::stream< T\>.write(T&); Write the element of type T to the stream, if the destination interface is not ready then this call will block. `uint w_uint =32; uistrm.write(w_uint);` The C++ “<<” operator can also be used to write data into a stream. `uistrm << w_uint;` ### T hls::stream< T\>.read(); Is a blocking read operation, it will wait till data is available on the stream and returns the data; in the vsi::runtime implementation the calling thread is blocked from execution and will wait till some other thread puts data into the stream using hls::stream< T\>.write(T&); The read operation will pop the first element from the hls::stream FIFO and return to the user. `uint r_uint = uistrm.read();` The C++ “>>” operator can also be used to pop data from the stream FIFO. `uistrm >> r_uint;` ### bool hls::stream< T\>.write_nb(T&); Is a non-blocking write operation, will return “true” if the write was successful else it will return “false”. ``` uint w_uint = 32; if (uistrm.write_nb(w_uint)) { // write success code } else { // write fail code } ``` ### bool hls::stream< T\>.read_nb(T&); Is the non-blocking version of the read, if data is available the function will update the reference in the argument with the values and return “true” , it will return false if the data is not available. ``` uint r_uint; if (uistrm.read_bd(r_uint)) { // read successful } else { // read failed no data in the stream } ``` ### bool hls::stream< T\>.full(); Return “true” if there is no more space in the stream to write data, return “false” if there is space. ### bool hls::stream< T\>.empty(); Returns “true” if the stream is empty() , this can be used in conjunction with the read() method to implement non-blocking reads. ### Examples: #### Example 1: The hls::stream class can used to implement dependencies between blocks in a complete system. In the following code example, the function vsi_mem_ctl reads an input array , and sends the data to an output stream (out_stream); then waits for response from the another function on the stream “resp” before continuing to execute. ``` void vsi_memory_ctl(int in_arr[1024], hls::stream > &out_stream, hls::stream > &start, hls::stream > &resp) { static int count = 0 ; ap_axis_d<32> e; int i; printf("%s started %d\n",__FUNCTION__,count); // perform operation for (i = 0 ; i < 1024; i++) { e.data = in_arr[i]; e.last = (i == 1023); out_stream.write(e); // write to output stream if (e.last) printf("%s last detected %d\n",__FUNCTION__,i); } ap_axis_d<32> w ; w.data = 1; w.last = 1; // tell next function to start start.write(w); printf("%s sent start waiting for response\n",__FUNCTION__); // wait for response ap_axis_d<32> r = resp.read(); printf("%s done %d\n",__FUNCTION__,count++); } ``` #### Example 2: This functions reads from two AXI streams and converts them into a single stream with different IDs. ``` void stream_mux (hls::stream > &in1, hls::stream > &in2, hls::stream > &outp) { while (!in1.empty() || !in2.empty()) { // non blocking wait ap_axis_dkt out; ap_axis_dkt in; ap_uint<1> tid; bool set = false; if (!in1.empty()) { in = in1.read(); tid = 0; set = true; } else if (!in2.empty()) { in = in2.read(); tid = 1; set = true; } out.data = in.data; out.keep = in.keep; out.last = in.last; out.id = tid; if (set) outp.write(out); } ``` More examples can be found in the source $(VSI_INSTALL)/target/common/hls_examples/stream_mux/stream_mux.cc