基于脉动阵列的矩阵乘法加速(FPGA)
原本准备做FADDEV求逆矩阵算法的FPGA实现,其中有一个概念挺吸引人,就是:脉动阵列。
1、脉动阵列
先来讲讲脉动阵列的概念,脉动阵列其实是一种处理单元的结构。数据同步流过,能够减小降低重复访问,调高处理效率和资源消耗。
其实这是个比较旧的概念了,1982就有学者提出了。18年谷歌提出的TPU(Tensor Processing Unit)让这个概念回到大众视野,通过脉动阵列可以设计完成矩阵乘法和卷积的操作。今天先讲讲矩阵乘法的实现。
2、脉动阵列结构
我们直接上图来讲解脉动阵列的结构。图源来自(§4脉动阵列处理机 - 百度文库 (baidu.com))
先设两个进行叉乘的矩阵
这里就不讲矩阵的乘法怎么运算了,基本的线性代数知识。
上图即为脉动阵列进行矩阵乘法时的布局。这里讲一下,图中每一个处理单元(后文简称为PE)。每个PE的结构都是有一个乘法器和累加器构成。两个输入端,分别接收两矩阵的行与列,输出乘法再累加结果,并延不同方向输出矩阵值。
经过上图的流动就可以完成矩阵乘法。并且只花费了2n+1个时钟。
3、PE单元设计
我们了解了脉动阵列进行矩阵乘法的流程之后,就可以开始动手设计了。首先我们知道需要设计PE单元。在这个例子里PE单元可以看作下图
其中data_tmp忽略。也就是PE单元中需要两个输入端,三个输出端,并且完成乘法和累加的功能。那么我们可以根据这个需求建立模块。
直接上源码:
`timescale 1ns/1ns
module pe(
input clk,
input rstn,
input [3:0] a_curr,
input [3:0] b_curr,
output reg [3:0] a_last,
output reg [3:0] b_last,
output reg [7:0] data_out
);
wire [7:0] data_tmp;
always@(posedge clk or negedge rstn)
begin
if(!rstn)
begin
a_last<='d0;
b_last<='d0;
end
else
begin
a_last<=a_curr;
b_last<=b_curr;
end
end
always@(posedge clk or negedge rstn)
begin
if(!rstn)
data_out<='d0;
else
begin
data_out<=data_out+data_tmp;
end
end
multi_pipe u_multi_pipe(
.clk (clk),
.rst_n (rstn),
.mul_a (a_curr),
.mul_b (b_curr),
.mul_out (data_tmp)
);
endmodule
单元模块中直接调用了预先写好了的乘法器使用。编译通过后进行仿真。
4、搭建矩阵乘法用脉冲阵列
我们完成了PE单元的设计之后,就可以通过例化来搭建脉冲阵列,然后需要注意各行各列头一个脉冲阵列的输入序列需要延后一定的clk以实现流水线,具体可以看前面的图片。
具体例化很简单就不展示了,然后编写testbench进行仿真。
计算的矩阵是:
(第三行数据最后一位由于溢出导致数据不正常)
根据仿真可以看见从复位开始,经过9个周期完成矩阵乘法运算。由于乘法器使得产生了额外的时钟开销,笔者没有仔细考虑优化,后续会考虑优化,并且完善ip的通用性并降低资源开销与时钟开销。
5、总结
脉动阵列是一个比较旧但是在近几年焕发活力的结构,流水线的数据流入使得能够切合FPGA实现,后续会更新使用脉动阵列搭建矩阵卷积的实现。可以考虑优化,并且完善ip的通用性并降低资源开销与时钟开销。文章来源:https://www.toymoban.com/news/detail-428526.html
5、总结
脉动阵列是一个比较旧但是在近几年焕发活力的算法,流水线的数据流入使得能够切合FPGA实现,写的这个也只是探究一下结构,摸索一下,后续会更新使用脉动阵列搭建矩阵卷积的实现。文章来源地址https://www.toymoban.com/news/detail-428526.html
到了这里,关于基于脉动阵列的矩阵乘法加速(FPGA)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!