Класс Vivado HLS с членом типа hls :: stream & lt; int & gt; & amp; приводит к ошибке: «Константа» имеет несинтезируемый тип … & quot;

Я пытаюсь увидеть, возможно ли создать экземпляр класса в vivado_hls, который имеет hls :: stream<> ссылаться на членов, так что я могу напрямую читать / записывать поток без необходимости передавать поток в качестве аргумента по цепочке вызовов.

ПРИМЕЧАНИЕ: это в vivado_hls 2018.2, а модулем верхнего уровня для этого проекта является «ModuleX». Рассмотрим упрощенный сценарий ниже:

#include <hls_stream.h>
#include <ap_int.h>

using hls_int = ap_uint<32>;

class X
{
private:
hls::stream<hls_int> &s1;
hls::stream<hls_int> &s2;

public:
X(hls::stream<hls_int> &_s1, hls::stream<hls_int> &_s2) :
s1(_s1), s2(_s2)
{}

void Run()
{
hls_int s = s2.read();
hls_int out = s * 2;
s1.write(out);
}
};

void ModuleX(hls::stream<hls_int> &s1, hls::stream<hls_int> &s2)
{
#pragma HLS INTERFACE ap_ctrl_none PORT=return
#pragma HLS STREAM VARIABLE=s1 DEPTH=1
#pragma HLS STREAM VARIABLE=s2 DEPTH=1

static X x {s1, s2};

x.Run();
}

При таком подходе я получаю следующую ошибку: ERROR: [SYNCHK 200-11] ClassWithStreamRefs.cpp:18: Constant 'x.s2.V.V' has an unsynthesizable type 'i32P*' (possible cause(s): pointer to pointer or global pointer).

Я понимаю, что под капотом компилятор, вероятно, хранит ссылку как указатель на поток, но это должно быть ошибкой с инструментами для этого сценария, насколько я считаю, поскольку он блокирует, что я увидеть как действительный HLS.

Надеюсь, есть еще один способ реализовать то, что я ищу (ссылки, а не значения хранятся в классе).

Что-то еще, что я попробовал, это работало ниже. Тем не менее, это крайне нежелательно, поскольку этот подход добавляет 2 такта задержки (по 1 на входе и выходе — без веской причины).

#include <hls_stream.h>
#include <ap_int.h>

using hls_int = ap_uint<32>;

class X
{
public:
hls::stream<hls_int> s1;
hls::stream<hls_int> s2;
X()
{
#pragma HLS STREAM VARIABLE=s1 DEPTH=1
#pragma HLS STREAM VARIABLE=s2 DEPTH=1
}

void Run()
{
hls_int s = s2.read();
hls_int out = s * 2;
s1.write(out);
}
};

void ModuleX(hls::stream<hls_int> &s1, hls::stream<hls_int> &s2)
{
#pragma HLS INTERFACE ap_ctrl_none PORT=return
#pragma HLS INLINE
static X x;

x.s2.write(s2.read());
x.Run();
s1.write(x.s1.read());
}

Вот пример tcl-скрипта (хотя он в основном просто генерируется vivado_hls)

open_project ClassWithStreamRef
set_top ModuleX
add_files ClassWithStreamRefs.cpp -cflags "-std=c++11"open_solution "solution1"set_part {xczu19eg-ffvc1760-2-i} -tool vivado
create_clock -period 10 -name default
csynth_design

0

Решение

Я не уверен насчет основного механизма, но удаляю static квалификатор позволяет Vivado HLS 2018.2 синтезировать пример. Это, однако, делает новый экземпляр X при каждом вызове функции top, поэтому ее поля не сохраняются. В приведенном ниже примере это решается добавлением еще одной статической переменной в верхнюю функцию для сохранения и передачей ее по ссылке на Xконструктор.

#include <hls_stream.h>
#include <ap_int.h>

using hls_int = ap_uint<32>;

struct State
{
hls_int counter;
};

class X
{
private:
hls::stream<hls_int> &s1;
hls::stream<hls_int> &s2;
State& state;

public:
X(hls::stream<hls_int> &_s1, hls::stream<hls_int> &_s2, State& _state) :
s1(_s1), s2(_s2), state(_state)
{}

void Run()
{
hls_int s = s2.read();
s1.write(s + state.counter++);
}
};

void ModuleX(hls::stream<hls_int> &s1, hls::stream<hls_int> &s2)
{
#pragma HLS INTERFACE ap_ctrl_none PORT=return
#pragma HLS STREAM VARIABLE=s1 DEPTH=1
#pragma HLS STREAM VARIABLE=s2 DEPTH=1

static State state {0};
X x {s1, s2, state};

x.Run();
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]