1.矩阵乘法
工作环境:vivado hls 2019.1
时钟周期:10us
矩阵乘法的实现:
在不加约束的情况下并行处理数据,需要825个周期进行计算,结果如下:
1.1 对for循环进行unroll约束
在Directive窗口,下方三个for statement即程序中的三层循环
右键insert Directive,选择UNROLL约束指令,即把for循环展开,例如本例中最内层循环有4次,UNROLL后此4次循环并行进行计算,理论上是计算时间缩短4倍,但是由于数据之间的依赖性/系统读取数据速度的限制,并不能达到理想的计算加速4倍
添加UNROLL后代码中多一行#pragma HLS UNROLL
再次进行综合,所需周期减少至473,结果如下:
可以将三层循环均进行UNROLL,理论上可以缩短4x4x4倍计算时间,但是肯定达不到理论值
将所有for循环进行并行约束后,最终计算周期减少到328
1.2 对输入端口进行约束
在1.1中只对for循环进行了展开加速,本节介绍对输入端口进行约束
默认情况下,HLS语言生成的电路一次读取的数据为程序中定义的float类型的一个数,所以存放输入数据的寄存器为32位
在Directive窗口,下方matrix_mul中的A B C即程序中的输入输出数组
A为2维的4x4数组,对A右键insert Directive,选择ARRAY_RESHAPE约束指令,即一次读取A的一维数据(4个数),dimension(optional)可选择读取的维数
加完约束后程序里会多一句
#pragma HLS ARRAY_RESHAPE variable=A complete dim=1
complete dim即展开的是哪一维
再来看A的输入寄存器大小,已经变成了128位(32x4)
同样,我们可以将A、B、C都进行并行输入,将两个维度都展开
A、B、C的输入寄存器大小扩大至512位(32x4x4),由于将二维数组全部展开,原本C Type中对A、B、C 的定义是array,全部展开后vivado不再将其理解为数组所以变为pointer类型
1.2 对函数协议进行约束
默认协议下,vivado综合后的电路RTL接口有这6根信号线
我们可以对函数名Matrix_mul加约束来使用速度更快的AXI片内高速总线,选择INTERFACE指令,mode选择s_axilite
程序中会自动添加一句#pragma HLS INTERFACE s_axilite port=return
最后综合出的电路接口即为AXI接口,后续进行系统综合时可以直接调用AXI接口的函数电路