基于FPGA的卷积加速

基于FPGA的卷积并行加速其实有很多方法,例如脉动阵列、加法树等操作。本篇博客将介绍一下基于加法树的并行化设计。

其实总体原理也是很简单的。如下图所示,九个叶子节点是乘法器节点,分别代表九次乘法运算(卷积核是3*3的)。在得到乘法运算结果之后,将结果传送给加法节点。
基于FPGA的卷积加速_第1张图片

为了进一步增加并行性,加法树结构采用三叉树。即,对每三个子节点进行求和。最终得到一个部分和。

实现方式是写一个加法器模块,再写一个乘法器模块,之后再写一个总体的模块将这些乘法器和加法器进行结合。

PS:加法器和乘法器都是自己写的,并没有调用 IP 核,如果想实现浮点数运算,可以调用赛灵思的浮点数运算 IP 核。

// 加法器模块
module adder(
	input clk,
	input rst_n,
	input [15 : 0] a,
	input [15 : 0] b,
	input [15 : 0] c,
	output [15 : 0] result
);
reg [15 : 0] result_reg;

assign result = result_reg;
always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		result_reg <= 16'b0;
	else
	begin
		result_reg <= a + b + c;
	end
end 

endmodule
// 乘法器模块
module mult(
	input clk,
	input rst_n,
	input [15 : 0] a,
	input [15 : 0] b,
	output [15 : 0] result

);

reg [15:0]result_reg;

assign result = result_reg;

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
	begin
		result_reg <= 16'b0;
	end
	
	else
	begin
		result_reg <= a * b;
	end

end 


endmodule
module tree(
	input clk,
	input rst_n,
	output [15 : 0]result
);

reg [15 : 0] result_reg;
wire [15:0] mult_w [8:0];

wire [15 : 0] adder_w [2 : 0];
reg [15:0] num_reg [8:0];


genvar i;
generate
	for(i = 0; i < 9; i = i + 1)
	begin: mults
		mult
		u_mult(
			.clk(clk),
			.rst_n(rst_n),
			.a(num_reg[i]),
			.b(num_reg[i]),
			.result(mult_w[i])
		);
	end 

endgenerate

genvar j;
generate
	for(j = 0; j < 3; j = j + 1)
	begin: adders
		adder
		u_adder(
			.clk(clk),
			.rst_n(rst_n),
			.a(mult_w[j * 3 + 0]),
			.b(mult_w[j * 3 + 1]),
			.c(mult_w[j * 3 + 2]),
			.result(adder_w[j])
		);
	end
endgenerate

adder
fin_adder(
	.clk(clk),
	.rst_n(rst_n),
	.a(adder_w[0]),
	.b(adder_w[1]),
	.c(adder_w[2]),
	.result(result)
);

integer s;
always@(posedge clk)
begin
    if(!rst_n)
    begin
        result_reg <= 16'b0;
        for(s = 0; s < 8; s = s + 1)
        begin
            num_reg[s] <= 16'd0;
        end
    end
    else
    begin
        
    end
end

genvar l;
generate
    for(l = 0; l < 9; l = l + 1)
    begin:nums
        always@(posedge clk or posedge rst_n)
        begin
            if(rst_n)
                num_reg[l] <= l + 1;
        end
    end
endgenerate


endmodule

RTL 分析:

基于FPGA的卷积加速_第2张图片

仿真结果:
基于FPGA的卷积加速_第3张图片

至于实现效率方面的话,其实是没有脉动阵列效率高的,并且基于加法树其实本质上还是串行操作。基于脉动阵列的仿真结果如下:
基于FPGA的卷积加速_第4张图片
本人实现了基于脉动阵列的 Eyeriss 项目,并在 AX7020 开发板上调试通过,有需要的可以私信我。

你可能感兴趣的:(FPGA硬件设计,深度学习编译,FPGA,深度学习加速,verilog,加速卷积)