如 阻塞 API 中所述,阻塞 API 可包含确定性行为和不确定性行为,如以下代码示例所示:
func1()
{
while(!s.empty()) {
s.read();
}
}
在 C 语言仿真期间,到串流的数据始终可用,因此 while
循环会运行直至完成。但如果数据串流在硬件中运行时有单个气泡,while
循环就将退出,func1
将提前返回。这将导致 C 语言仿真与 RTL 执行之间出现不确定性行为。
实现此循环的正确方法是使用旁路信号 tlast
,如以下示例所示。如需了解更多信息,请参阅 含旁路的 AXI4-Stream 接口。
func1()
{
while(!tlast) {
s1.read()
}
}
通过以下任一方式使用阻塞 API 即可得到确定性行为。
- 案例 1:简单读/写 FIFO
-
int data = in.read(); if (data >= 10) out1.write(data); else out2.write(data);
- 案例 2:使用阻塞 API 执行 FULL(满)和 EMPTY(空)检查
-
此例不执行任何具有副作用的计算,即,读取或写入串流、存储器或静态变量仍被视为仅使用阻塞串流访问。
void df(hls::stream<...> &s1, hls::stream<...> &s2, ...) { #pragma HLS dataflow p1(s1, ...); p2(s2, ...); ... } void p1(hls::stream<...> &s1, ...) { if (s1.empty()) return; ... = s1.read(); ... } void p2(hls::stream<...> &s2, ...) { if (s2.full()) return; ... s2.write(...); }