一起学习用Verilog在FPGA上实现CNN----integrationConv设计

Posted 鲁棒最小二乘支持向量机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起学习用Verilog在FPGA上实现CNN----integrationConv设计相关的知识,希望对你有一定的参考价值。

1 integrationConv设计

LeNet-5网络结构卷积部分如图所示,该部分有3个卷积层,3个TanH激活层,2个平均池化层:


图片来自附带的技术文档《Hardware Documentation》

  • 输入图像大小为32x32,因此第一层卷积Conv1的输入为32x32,卷积核设置:大小为5x5,数量为6,Conv1的输出特征大小为28x28x6;第一层激活层TanH1的输入为28x28x6,输出为28x28x6;第一层平均池化AvgPool1的输入为28x28x6,输出为14x14x6

  • 第二层卷积Conv2的输入为14x14x6,卷积核设置:大小为5x5,数量为16x6,Conv2的输出特征大小为10x10x16;第二层激活层TanH2的输入为10x10x16,输出为10x10x16;第二层平均池化AvgPool2的输入为10x10x16,输出为5x5x16

  • 第三层卷积Conv3的输入为5x5x16,卷积核设置:大小为5x5,数量为120x16,Conv3的输出为1x1x120;第三层激活层TanH3的输入为1x1x120,输出为1x1x120

2 integrationConv程序

修改代码如下:

module integrationConv (clk,reset,CNNinput,Conv1F,Conv2F,Conv3F,iConvOutput);

parameter DATA_WIDTH = 16;
parameter ImgInW = 32;
parameter ImgInH = 32;
parameter Conv1Out = 28;
parameter AvgP1out = 14;
parameter Conv2Out = 10;
parameter Kernel = 5;
parameter AvgP2out = 5;
parameter Conv3Out = 1;
parameter DepthC1 = 6;
parameter DepthC2 = 16;
parameter DepthC3 = 120;

integer counter;

input clk, reset;
input [ImgInW*ImgInH*DATA_WIDTH-1:0] CNNinput;
input [Kernel*Kernel*DepthC1*DATA_WIDTH-1:0] Conv1F;
input [DepthC2*Kernel*Kernel*DepthC1*DATA_WIDTH-1:0] Conv2F;
input [DepthC3*Kernel*Kernel*DepthC2*DATA_WIDTH-1:0] Conv3F;
output [DepthC3*DATA_WIDTH-1:0] iConvOutput;

reg C1rst,C2rst,C3rst,AP1rst,AP2rst,Tanh1Reset,Tanh2Reset,Tanh3Reset;
wire Tanh1Flag,Tanh2Flag,Tanh3Flag;

wire [Conv1Out*Conv1Out*DepthC1*DATA_WIDTH-1:0] C1out;
wire [Conv1Out*Conv1Out*DepthC1*DATA_WIDTH-1:0] C1outTanH;

wire [AvgP1out*AvgP1out*DepthC1*DATA_WIDTH-1:0] AP1out;

wire [Conv2Out*Conv2Out*DepthC2*DATA_WIDTH-1:0] C2out;
wire [Conv2Out*Conv2Out*DepthC2*DATA_WIDTH-1:0] C2outTanH;

wire [AvgP2out*AvgP2out*DepthC2*DATA_WIDTH-1:0] AP2out;

wire [Conv3Out*Conv3Out*DepthC3*DATA_WIDTH-1:0] C3out;

convLayerMulti C1
(
	.clk(clk),
	.reset(reset),
	.image(CNNinput),
	.filters(Conv1F),
	.outputConv(C1out)
);

UsingTheTanh16
#(.nofinputs(Conv1Out*Conv1Out*DepthC1))
Tanh1(
      .x(C1out),
      .clk(clk),
      .Output(C1outTanH),
      .resetExternal(Tanh1Reset),
      .FinishedTanh(Tanh1Flag)
      );

AvgPoolMulti AP1
  (
    .clk(clk),
    .reset(reset),
    .apInput(C1outTanH),
    .apOutput(AP1out)
  );
convLayerMulti
#(
  .DATA_WIDTH(16),
  .D(6),
  .H(14),
  .W(14),
  .F(5),
  .K(16)
) C2 
(
	.clk(clk),
	.reset(reset),
	.image(AP1out),
	.filters(Conv2F),
	.outputConv(C2out)
);

UsingTheTanh16
#(.nofinputs(Conv2Out*Conv2Out*DepthC2))
Tanh2(
      .x(C2out),
      .clk(clk),
      .Output(C2outTanH),
      .resetExternal(Tanh2Reset),
      .FinishedTanh(Tanh2Flag)
      );

AvgPoolMulti 
  #(
  .D(16),
  .H(10),
  .W(10)
  ) AP2
  (
    .clk(clk),
    .reset(reset),
    .apInput(C2outTanH),
    .apOutput(AP2out)
  );

convLayerMulti C3 
(
	.clk(clk),
	.reset(reset),
	.image(AP2out),
	.filters(Conv3F),
	.outputConv(C3out)
);

UsingTheTanh16
#(.nofinputs(Conv3Out*Conv3Out*DepthC3))
Tanh3(
      .x(C3out),
      .clk(clk),
      .Output(iConvOutput),
      .resetExternal(Tanh3Reset),
      .FinishedTanh(Tanh3Flag)
      );  
      
always @(posedge clk or posedge reset) begin
  if (reset == 1'b1) begin
    C1rst = 1'b1;
    C2rst = 1'b1;
    C3rst = 1'b1;
    AP1rst = 1'b1;
    AP2rst = 1'b1;
    Tanh1Reset = 1'b1;
    Tanh2Reset = 1'b1;
    Tanh3Reset = 1'b1;
    counter = 0;
  end
else begin
  counter = counter + 1;
  if (counter > 0 && counter < 7*1457) begin
       C1rst = 1'b0;
    end
  else if (counter > 7*1457 && counter < 7*1457+6*784*6) begin
       Tanh1Reset = 1'b0;
    end
  else if (counter > 7*1457+6*784*6 && counter < 7*1457+6*784*6+8) begin
       AP1rst = 1'b0;
    end
  else if (counter > 7*1457+6*784*6+8 && counter < 7*1457+6*784*6+8+18*22*152) begin
       C2rst = 1'b0;
    end 
  else if (counter > 7*1457+6*784*6+8+18*22*152 && counter < 7*1457+6*784*6+8+18*22*152 + 6*1600) begin
      Tanh2Reset = 1'b0;
    end
  else if (counter > 7*1457+6*784*6+8+18*22*152 + 6*1600 && counter < 7*1457+6*784*6+8+18*22*152 + 6*1600 + 20) begin
       AP2rst = 1'b0;
    end
  else if (counter > 7*1457+6*784*6+8+18*22*152 + 6*1600 + 20 && counter < 7*1457+6*784*6+8+18*22*152 + 6*1600 + 20 + 30) begin
       C3rst = 1'b0;
    end   
  else begin
       Tanh3Reset = 1'b0;
    end 
  end
end
endmodule

如图所示:

对设计进行分析,操作如图:

分析后的设计,Vivado自动生成原理图,如图:

原理图如下:

希望本文对大家有帮助,上文若有不妥之处,欢迎指正

分享决定高度,学习拉开差距

以上是关于一起学习用Verilog在FPGA上实现CNN----integrationConv设计的主要内容,如果未能解决你的问题,请参考以下文章

一起学习用Verilog在FPGA上实现CNN----integrationFC设计

一起学习用Verilog在FPGA上实现CNN----池化层设计

一起学习用Verilog在FPGA上实现CNN----integrationConv设计

一起学习用Verilog在FPGA上实现CNN----SoftMax层设计

一起学习用Verilog在FPGA上实现CNN----全连接层设计

一起学习用Verilog在FPGA上实现CNN----卷积层设计