含串流接口且不含 config 输入的 run()
函数在 HLS 名称空间内的定义方式如下:
void run(
hls::stream<in_data_t> &in_V,
hls::stream<out_data_t> &out_V);
含 config 输入时,其定义方式如下:
void run(
hls::stream<in_data_t> &in_V,
hls::stream<out_data_t> &out_V,
hls::stream<config_t> &config_V);
FIR 函数在 HLS 名称空间内定义,可按如下方式调用:
// Create an instance of the FIR
static hls::FIR<STATIC_PARAM> fir1;
// Execute the FIR instance fir1
fir1.run(INPUT_DATA_STREAM, OUTPUT_DATA_STREAM);
STATIC_PARAM 属于静态参数化结构体,用于为 FIR 定义大部分静态参数。输入数据和输出数据都作为 hls::stream<>
提供给函数。FIR IP 上的这些端口将作为 AXI4‑Stream 端口来实现。
AMD 建议在使用 set_directive_dataflow
或 #pragma HLS
dataflow
的数据流区域内始终使用 FIR 函数。
重要: FIR 无法在经流水打拍的区域内使用。如需高性能运算,请在使用 FIR 前后分别对循环或函数进行流水打拍,并对区域内的所有循环和函数使用 DATAFLOW 编译指示或指令,如以下示例所示。
通过在单一输入和单一输出串流内进行数据交织来支持 FIR 的多通道功能。
- 输入串流的大小应足以保存所有样本:
num_channels * input_length
- 输出数据大小应指定为可包含所有输出样本:
num_channels * output_length
以下代码示例演示了 FIR IP 函数的使用方式。
template<typename data_t, int LENGTH>
void process_fe(data_t in[LENGTH], hls::stream<data_t> &out)
{
for(unsigned i = 0; i < LENGTH; ++i)
out.write(in[i]);
}
template<typename data_t, int LENGTH>
void process_be(hls::stream<data_t> &in, data_t out[LENGTH])
{
for(unsigned i = 0; i < LENGTH; ++i)
out[i] = in.read();
}
// TOP function
void fir_top(
data_t in[FIR1_LENGTH],
data_out_t out[FIR2_LENGTH])
{
#pragma HLS dataflow
hls::stream<data_t> fir1_in;
hls::stream<data_intern_t> fir1_out;
hls::stream<data_out_t> fir2_out;
// Create FIR instance
static hls::FIR<config1> fir1;
static hls::FIR<config2> fir2;
//==================================================
// Dataflow process
process_fe<data_t, FIR1_LENGTH>(in, fir1_in);
fir1.run(fir1_in, fir1_out);
fir2.run(fir1_out, fir2_out);
process_be<data_out_t, FIR2_LENGTH>(fir2_out, out);
//==================================================
}
提示: 为避免执行 FIR 过程中出现气泡,您需要使用
config_dataflow -fifo_depth
命令确保 FIFO 深度足以满足数据流区域内的数据吞吐量,并且可能需要对 process_fe
和 process_be
中的循环应用循环回绕,如 PIPELINE 编译指示或指令中所述。