HLS 编程实战记录

旧时模样 提交于 2020-01-17 09:59:22

说明:

     自己以前是编写verilog代码,今年Xilinx开始大推Vitis,即用软件定义硬件,好奇就尝试了项目中一部分算法采用HLS实现,此文章仅记录尝试过程中的一些坑以及一些解决方法,欢迎大家留言指点讨论。

 

1. 当数组作为函数的参数的时候,如果不设置数组的大小,只是传递了一个指针,在Simulation的时候,不会报错,但是在Synthesis的时候就报错,因为不知道该指针的大小,没办法映射FPGA的资源,下面的例子如下

                            void example_no_label(int A[50], int B[50]);

 

2. HLS testbench定义的一些变量最好给个初值,要不然仿真的时候会出现一些错乱值.同理也适用于CPU运行环境中。

 

3.Directive中的unroll意思是循环直接并行执行,flatten应用在假如有两个循环嵌套的时候,两个循环合并为一个循环执行。

 

4. 当出现 叠加操作,即类似下面的操作,这么修改避免了对同一个FIFO即读又写,消耗时间,即能使用内部寄存器,就不访问外部存储空间

sum=1;

for(int i=0;i<10;i++){

  sum=sum+i;
}

修改为
A=1;

for(int i=0;i<10;i++){
  A=A+i;
  sum=A;
}

 

5. 在testbench中读取文件的时候必须使用绝对路径,测试过程中,如果不使用绝对路径,在仿真的时候可能没问题,但是在联合仿真的时候会出现错误,具体出错内容如下:

ERROR: System recieved a signal named SIGSEGV and the program has to stop immediately!
This signal was generated when a program tries to read or write outside the memory that is allocated for it, or to write memory that can only be read.
Possible cause of this problem may be: 1) the depth setting of pointer type argument is much larger than it needed; 2)insufficient depth of array argument; 3)null pointer etc.
Current execution stopped during CodeState = DELETE_CHAR_BUFFERS.
You can search CodeState variable name in apatb*.cpp file under ./sim/wrapc dir to locate the position.


ERROR: [COSIM 212-360] Aborting co-simulation: C TB simulation failed.
ERROR: [COSIM 212-320] C TB testing failed, stop generating test vectors. Please check C TB or re-run cosim.
ERROR: [COSIM 212-5] *** C/RTL co-simulation file generation failed. ***
ERROR: [COSIM 212-4] *** C/RTL co-simulation finished: FAIL ***
command 'ap_source' returned error code
    while executing
"source /home/wqj/GMM/gmm_hls/HLS_V6/gmm_gauss_hls/solution1/cosim.tcl"
    invoked from within
"hls::main /home/wqj/GMM/gmm_hls/HLS_V6/gmm_gauss_hls/solution1/cosim.tcl"
    ("uplevel" body line 1)
    invoked from within
"uplevel 1 hls::main {*}$args"
    (procedure "hls_proc" line 5)
    invoked from within
"hls_proc $argv"

 

6.在函数的声明里面,有 float *r,在联合仿真的时候出错,后来xilinx给的建议是软件bug,建议直接换个变量名字,所以在变量的声明中最好使用带前缀得变量,防止踩雷

7.在采用sin等函数进行浮点定点计算的时候,这个时候头文件包括ap_fixed.h hls_math.h using namespace hls ,这个时候调用的sin等函数可以直接进行定点浮点的运算.如果不包括using namespace hls 或者不适用hls::sin这种形式,直接采用sin进行计算,调用的是标准的C或者C++函数

  •  定点之间可以直接进行加减乘数
  • 定点与浮点之间的运算必须进行强制类型转换.
  • 为了减少资源使用.在浮点数据定点化的时候,不仅需要对接口的输入输出数据定点化操作,还需要函数内部跟定点交互的运算,做一些强制类型转换,即定点与浮点之前不能直接计算.

 

8.当函数的接口参数类型为浮点类型的时候,我到底该怎么在RTL中赋值呢。IEEE754跟按照1.8.23转换的方法有什么区别

 函数的接口类型只认16进制的形式,直接赋值为十进制的形式是不认的。

9.vivado中的浮点的乘法IP跟IEEE754的之间关系,即满足IEEE754关系的数据能直接进行使用IP吗?

10.当HLS中的接口为int或者float类型的时候,在verilog中赋值的时候必须是按照IEEE754标准的16进制形式,当为uint类型的时候就可以直接复制为10进制,即assign a=32‘d10,这种格式,当为定点类型的时候,必须转换为16进制形式的进行赋值,具体的参考’HLS 定点存为vivado testbench可以获取的格式  这个文章。就比如激光点云的坐标为有符号的十进制,在进行角度转换的时候,采用的是定点的24bit进制,这个时候必须把点云坐标的十进制转换为16进制显示才可以进行角度转化模块。

11. 当函数的输出为return形式的时候,注意return不能是一个指针,另外return的完成是参考ap_done信号的。

12. 当执行一些运算输出的时候,可能会出现如下的一些错误,即有2个100ps的错误数据,(两个flaot类型的的加法)

float float_add(float a,float b,float e,float f, float *c){
	*c=a+b;
	float d;
	d=e+f;
	return d;
}

可以通过添加register的方式去掉错误

另外一种解决方法如下所示:

但是还是不清楚为什么修改为ap_hs,毛刺就消失了,因为查看综合后的RTL,是在RTL中对输出自动增加了reg时序缓存,类似与在directive中添加register

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!