本文关注点:
HLS设计为什么需要C Testbench?
C Testbench的构成要素?
什么是高效的C Testbench?
高层次综合(High Level Synthesis, HLS)越来越受到算法工程师和软件工程师的关注。同时,工程师们也容易忽视C Testbench(基于C/C++的仿真文件)的重要性与必要性。
为什么需要C Testbench?
通常,我们在创建一个HLS工程后,第一件要做的事情是在C层面验证待综合的函数的功能是否正确。这就要求必须提供相应的C Testbench。一方面,基于C/C++的算法级仿真远比传统的RTL级仿真更快,也更高效。这种高效体现在C语言相比于硬件描述语言例如VHDL或Verilog具有更高的抽象度,这使得采用C/C++描述Testbench变得相对容易。例如,可以快捷地对文件进行读写操作、对输出结果进行比对等,而这些都无需考虑时序需求。另一方面,Vivado HLS在完成C到RTL的转换后,也需要对生成的RTL模型进行功能验证。这种验证需要C Testbench才能完成。因为工具会根据C Testbench生成RTL Testbench(并不会真正生成相应的文件),如果没有C Testbench,就无法对RTL模型进行验证,因此,这一步也被称之为C/RTL协同仿真(C/RTL Co-simulation)。概括下来,无论是C层面的仿真还是C/RTL的协同仿真都离不开C Testbench。
C Testbench的构成要素
C Testbench至少需要有以下几个构成要素:输入激励、调用待综合函数、输出对比。输入激励很好理解,就是给待综合函数提供数据源。这些数据可以来自内部数组或外部文件。对输入激励的一个基本要求是尽可能地提高数据的多样性,以保证代码覆盖率,从而提高测试的完备性。既然是对待综合函数进行验证,就需要对其进行调用,将输入激励给到该函数,获取其输出。输出对比环节则是将待综合函数的输出与参考输出进行对比,以检查输出是否正确。在这一步,如果对比结果完全一致,则main函数返回0,否则返回非0整数。这里,Xilinx建议main函数的返回值控制在8-bit数据所能表示的范围之内。通常,验证失败时,返回值设置为1。同时还需注意,用户必须保证C Testbench对输出结果进行了检测,如果没有检测,却设置返回值为0,工具仍会认为仿真通过。
什么是高效的C Testbench?
待综合的顶层函数被多次调用
可将调用次数以宏(Macro)的形式定义在头文件中,便于修改。多次调用待综合函数是为了保证足够多的输入激励被提供,从而提高代码覆盖率。
提供参考模型或参考数据
C Testbench中一定要有数据对比环节,就是将待综合函数的输出与参考数据进行对比。因此,参考模型或参考数据是必须要有的。这里需要注意,凡是C Testbench中访问的文件,例如输入激励文件或者输出数据参考文件,都要将其归为仿真文件,一同添加到HLS工程中。
C Testbench要和待综合函数写入不同的文件
这个不是必须的。但从代码风格和HLS工程管理角度而言,这样做是有好处的。通常,数据类型等可定义在头文件中,待综合的函数和C Testbenc分开单独描述。