流水操作整个函数
新建解决方案然后选择顶层的matrixmul标签添加PIPELINE指令,并移除Col中的流水操作,如下图所示:
添加完成后运行C综合,然后分析报告,进行对比流水内部循环和整个函数的区别。
该设计现在以更少的时钟完成,并且可以每 5 个时钟周期开始一个新的事务。 然而,由于设计中的所有环路都展开了,因此面积和资源大幅增加。流水线循环允许循环保持滚动,从而提供了控制区域的好方法。 流水线化整个函数时,函数中包含的所有循环都被展开,这是流水线化的要求。 流水线功能设计可以每 5 个时钟周期处理一组新的 9 个样本。 这超出了每个时钟 1 个样本的要求,因为高级综合的默认行为是生成具有最高性能的设计。
流水线整个函数产生的是最佳性能。 但是,如果它超过了所需的性能,则可能需要多个额外的指令来减慢设计速度。流水线循环为您提供了一种控制资源的简单方法,可选择部分展开设计以满足性能要求。
使用FIFO接口
完成对内部数据处理后,处理函数的接口。设计要求使用FIFO接口。现在进行新建解决方案,然后在a、b、res这三个数组进行设置使用FIFO接口。添加接口指令如下:
完成指令添加后点击运行C综合,此时无法正常综合,报错如下:
从图中的代码中,数组 res 按以下顺序执行写操作(MAT_B_COLS = MAT_B_ROWS = 3):
- 在57行写入
[0][0]
; - 在60行写入
[0][0]
; - 在60行写入
[0][0]
; - 在60行写入
[0][0]
; - 在第 57 行写入
[0][1]
(在索引 J 增加之后); - 在60行写入
[0][0]
;
对地址 [0][0] 的连续四次写入不构成流式访问模式 ; 这是随机访问。所以无法使用流接口。 C 代码的性质(指定对相同地址的多次访问)阻止了流接口的应用。在流接口中,必须按顺序访问这些值。
读取数组 a 和 b 存在类似的问题。 不可能使用 FIFO 接口通过编写的代码进行数据访问。 要使用 FIFO 接口,Vivado 高级综合中可用的优化指令是不够的,因为代码当前强制执行特定的读取和写入顺序。 进一步优化需要重写代码。
下图显示了之前的代码的数据IO访问模式。
由于变量 i、j 和 k 从 0 到 3 迭代,下半部分显示了读取 a、b 和写入 res 时生成的地址。 此外,在每个 Product 循环开始时, res 设置为零值。
对于具有顺序流访问的硬件设计,端口访问只能是以红色突出显示的那些。 对于读端口,数据必须在内部缓存,以确保设计不必重新读取端口。 对于写端口 res,数据必须保存到一个临时变量中,并且只能在红色显示的周期内写入端口。
所以要对设计进行拓展实现图中的数组的赋值操作。main函数修改成下面:
#include "matrixmul.h" void matrixmul( mat_a_t a[MAT_A_ROWS][MAT_A_COLS], mat_b_t b[MAT_B_ROWS][MAT_B_COLS], result_t res[MAT_A_ROWS][MAT_B_COLS]) { mat_a_t a_row[MAT_A_ROWS]; mat_b_t b_copy[MAT_B_ROWS][MAT_B_COLS]; int tmp = 0; // Iterate over the rowa of the A matrix Row: for(int i = 0; i < MAT_A_ROWS; i++) { // Iterate over the columns of the B matrix Col: for(int j = 0; j < MAT_B_COLS; j++) { // Do the inner product of a row of A and col of B tmp=0; // Cache each row (so it's only read once per function) if (j == 0) Cache_Row: for(int k = 0; k < MAT_A_ROWS; k++) a_row[k] = a[i][k]; // Cache all cols (so they are only read once per function) if (i == 0) Cache_Col: for(int k = 0; k < MAT_B_ROWS; k++) b_copy[k][j] = b[k][j]; Product: for(int k = 0; k < MAT_B_ROWS; k++) { tmp += a_row[k] * b_copy[k][j]; } res[i][j] = tmp; } } }
指令修改成下图:
此时进行C综合可以完成综合,对比之前设计,此时的延迟进一步被优化,而资源仅仅在FF和LUT进行少量的增加。
references
- UG871