Intel®高层次综合编译器专业版: 最佳实践指南

ID 683152
日期 12/04/2023
Public
文档目录

10.1. 仅在仿真中出现的组件失败

模拟(-march=X86-64)模式或仿真(-march=FPGA_name_or_part_no )模式下编译组件结果之间的差异通常取决于您组件或测试台中未定义或已定义的实现行为。但某些常见情况下,其它原因也会引起差异。

比较浮点结果

在测试台中比较浮点值时,请使用epsilon(ɛ)。RTL硬件中的浮点结果不同于x86 模拟流程。

使用#pragma ivdep以忽略存储器依赖性。

如果您试图忽略的组件存储依赖性带有#pragma ivdep编译器编译指令,则组件中的该编译指令可能导致组件中的功能不正确。可尝试使用safelen修改程序控制出现存储器依赖性之前可允许的存储器访问数量。

查看 Intel® High Level Synthesis Compiler Pro Edition参考手册中的Loop-Carried Dependencies (ivdep Pragma)了解有关编译指令的说明。

要了解使用ivdep编译指令的实例,请在 <quartus_installdir>/hls/examples/tutorials/best_practices/loop_memory_dependency中查看教程。

查看未初始化的变量

许多编码实践会造成C++规范未定义的行为。有时,该未定义行为在模拟中为一种方式,而在仿真中为另一种方式。

在设计读取未初始化的变量(尤其是未初始化的struct变量)时,就会出现该情况下的常见实例。

查看您代码中未初始化的值,并使用-Wuninitialized编译器标记,或使用valgrind调试工具调试您的模拟测试台。-Wuninitialized编译器标记并不会显示未初始化struct变量。

还可使用1个或多个流接口作为调试流来检查未正常运行的行为。可向组件添加1个或多个ihc::stream_out接口,以使组件在执行时写出其内部状态变量。通过比较模拟流程和仿真流程的输出,可看到RTL行为与模拟行为的区别。

Non-blocking流访问

tryRead()模拟模型的周期不准确,因此在模拟和仿真之间tryRead()的行为会有所不同。

如果流中具有FIFO(即,ihc::buffer<>模板参数)的non-blocking流访问(例如,tryRead()),则仿真中的前几个tryRead()迭代可能会返回false,但在模拟中则返回true

该情况下,可从测试台额外调用组件几次,以确保其使用流中的所有数据。这些额外调用不会引起功能性问题,因为tryRead()会返回false

通过ihc_hls_enqueue()ihc_hls_enqueue_noret()调用组件

如果通过ihc_hls_enqueue()ihc_hls_enqueue_noret()调用您的组件,请确保您也调用了ihc_hls_component_run_all()

如果您未调用ihc_hls_component_run_all(),您的组件会模拟失败。