Xilinx / Vitis-HLS-Introductory-Examples

Other
599 stars 158 forks source link

Working with objects and hls::task #15

Open fabrizio-ottati opened 1 year ago

fabrizio-ottati commented 1 year ago

Hi everyone, I have a question regarding the usage of hls::task when using an OOP structure for the design. Suppose to have the following design in main.cc:

#include <hls_task.h>

class Counter {
  unsigned int _cnt=0; 

  public:
  Counter(void) = default; 

  void stream(
    hls::stream<bool>& inStream, 
    hls::stream<unsigned int>& outStream
    ) {
    if (inStream.read()) {
      outStream.write(_cnt++); 
    }
  }
};

void dut(
  hls::stream<bool>& inStream, 
  hls::stream<unsigned int>& outStream
  ) {
#pragma HLS dataflow
  hls_thread_local Counter cnt; 
  hls_thread_local hls::task t(cnt.stream, inStream, outStream); 
}

Using the following Makefile:

VITIS_ROOT := /eda/xilinx/Vitis_HLS/2022.2/include
CXX := /usr/bin/g++

all:
    $(CXX) main.cc -o main.out -I$(VITIS_ROOT)

When compiling the design:

fab@fedora: $ make
/usr/bin/g++ main.cc -o main.out -I/eda/xilinx/Vitis_HLS/2022.2/include
main.cc: In function ‘void dut(hls::stream<bool>&, hls::stream<unsigned int>&)’:
main.cc:25:36: error: invalid use of non-static member function ‘void Counter::stream(hls::stream<bool>&, hls::stream<unsigned int>&)’
   25 |   hls_thread_local hls::task t(cnt.stream, inStream, outStream);

If we try in Vitis HLS:

vitis_hls> csynth_design 
INFO: [HLS 200-1510] Running: csynth_design 
INFO: [HLS 200-111] Finished File checks and directory preparation: CPU user time: 0.01 seconds. CPU system time: 0.01 seconds. Elapsed time: 0.01 seconds; current allocated memory: 772.094 MB.
INFO: [HLS 200-10] Analyzing design file 'main.cc' ... 
ERROR: [HLS 207-2295] reference to non-static member function must be called (main.cc:25:36)

Since when compiling this design I get the error ERROR: Invalid use of non-static member function from the compiler, what is the best solution to wrap the method of a class so that it can be used in an hls::task? With exposed objects like the one I posted here, I can define some helper functions and use the objects as global variables, but now I am starting to call the tasks inside the class itself and this is not feasible anymore. I tried a lambda but it doesn't work. This is the error I get in execution of the C simulation:

terminate called after throwing an instance of 'std::system_error'
  what(): Resource temporarily unavailable.

Thanks in advance :)