一起学习用Verilog在FPGA上实现CNN----(三)激活层设计

news2024/11/25 3:03:55

1 激活层设计

LeNet-5网络的激活函数是双曲正切函数(TanH),项目中tanh函数模块由完整的层UsingTheTanh构成,该层由较小的处理单元HyperBolicTangent组成

1.1 HyperBolicTangent

处理单元HyperBolicTangent,对每个输入执行Tanh操作,原理图如图所示,输入为位宽16的数,输出位宽也是16。该单元将Tanh运算分为3个乘法操作和1个加法操作:

  • 首先,得到x项的增量项,即x^2
  • 然后,将当前x项与下一项相乘
  • 然后,将每个相应的最终x项与其系数相乘
  • 最后,将每个结果项与前一项相加

在这里插入图片描述

1.2 UsingTheTanh

UsingTheTanh是Tanh层,由HyperBolicTangent单元组成,原理图如图所示。Tanh层的输入数据位宽为75264,即为卷积层的输出数据

在这里插入图片描述

2 代码实现

一起学习用Verilog在FPGA上实现CNN----(二)卷积层设计已经完成卷积层的设计,下面我们继续激活层的代码实现

2.1 HyperBolicTangent16

2.1.1 设计输入

创建HyperBolicTangent16文件,操作如图:

在这里插入图片描述

输入文件名:

在这里插入图片描述

确认创建:

在这里插入图片描述
双击打开,输入如下代码:

module HyperBolicTangent16 (x,reset,clk,OutputFinal,Finished);
parameter DATA_WIDTH=16;
localparam taylor_iter=4;//I chose 4 Taylor Coefficients to undergo my tanh operation
input signed [DATA_WIDTH-1:0] x;

input clk;
input reset;
output reg Finished;
output reg[DATA_WIDTH-1:0]  OutputFinal;
reg [DATA_WIDTH*taylor_iter-1:0] Coefficients ; //-17/315 2/15 -1/3 1
wire [DATA_WIDTH-1:0] Xsquared; //To always generate a squared version of the input to increment the power by 2 always.
reg [DATA_WIDTH-1:0] ForXSqOrOne; //For Multiplying The power of X(1 or X^2)
reg [DATA_WIDTH-1:0] ForMultPrevious; //output of the first multiplication which is either with 1 or x(X or Output1)
wire [DATA_WIDTH-1:0] OutputOne; //the output of Mulitplying the X term with its corresponding power coeff.
wire [DATA_WIDTH-1:0] OutOfCoeffMult; //the output of Mulitplying the X term with its corresponding power coeff.
reg  [DATA_WIDTH-1:0] OutputAdditionInAlways;
wire [DATA_WIDTH-1:0] OutputAddition; //the output of the Addition each cycle 

floatMult16 MSquaring (x,x,Xsquared);//Generating x^2   得到x项的增量项,即x^2
floatMult16 MGeneratingXterm (ForXSqOrOne,ForMultPrevious,OutputOne); //Generating the X term [x,x^3,x^5,...]  将当前x项与下一项相乘
floatMult16 MTheCoefficientTerm (OutputOne,Coefficients[DATA_WIDTH-1:0],OutOfCoeffMult); //Multiplying the X term by its corresponding coeff. 将每个相应的最终x项与其系数相乘
floatAdd16 FADD1 (OutOfCoeffMult,OutputAdditionInAlways,OutputAddition); //Adding the new term to the previous one     ex: x-1/3*(x^3) 将每个结果项与前一项相加
reg [DATA_WIDTH-1:0] AbsFloat; //To generate an absolute value of the input[For Checking the convergence]

always @ (posedge clk) begin
AbsFloat=x;//Here i hold the input then i make it positive whatever its sign to be able to compare to implement the rule |x|>pi/2   which is the convergence rule
AbsFloat[15]=0;
if(AbsFloat>16'sb0011111001001000)begin 
  //The Finished bit is for letting the bigger module know that the tanh is finished
  if (x[15]==0)begin 
    OutputFinal= 16'b0011110000000000;Finished =1'b 1;//here i assign it an immediate value of Positive Floating one
  end 
    if (x[15]==1)begin 
    OutputFinal= 16'b1011110000000000;Finished =1'b 1;//here i assign it an immediate value of Negative Floating one
    end
end
//here i handle the case of it equals +- pi/2    so i got the exact value and handle it also immediately
else if (AbsFloat==16'sb0011111001001000)
  begin 
    if (x[15]==0)begin 
  OutputFinal=16'b0011110000000000;Finished=1'b 1;
  end
  else begin 
  OutputFinal=16'b1011110000000000;Finished=1'b 1;
  end
  end
else begin 
  //First instance of the tanh
if(reset==1'b1)begin  
	Coefficients=64'b1010101011101000_0011000001000100_1011010101010101_0011110000000000;//the 4 coefficients of taylor expansion
	ForXSqOrOne=16'b0011110000000000; //initially 1
	OutputAdditionInAlways=16'b0000000000000000; //initially 0
	ForMultPrevious=x;
Finished=0;
end
else begin
 	ForXSqOrOne=Xsquared;
	ForMultPrevious=OutputOne; //get the output of the second multiplication to multiply with x
	Coefficients=Coefficients>>DATA_WIDTH; //shift 32 bit to divide the out_m1 with the new number to compute the factorial
  OutputAdditionInAlways=OutputAddition;
  Finished=0;
end
// the end of the tanh
if(Coefficients==64'b0000000000000000_0000000000000000_0000000000000000_0000000000000000)begin 
	OutputFinal=OutputAddition;
	Finished =1'b 1;
end
end 
end
endmodule 

如图所示:

在这里插入图片描述

2.1.2 分析与综合

将HyperBolicTangent16设置为顶层:

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

对设计进行综合,操作如图:

在这里插入图片描述

综合完成,关闭即可:

在这里插入图片描述

2.1.3 功能仿真

创建TestBench,操作如图所示:

在这里插入图片描述

输入激励文件名:

在这里插入图片描述

双击打开,输入激励代码:

`timescale 1ns / 1ps
module tb_HyperBolicTangent16();
reg clk, reset;
reg [15:0]x;
wire [15:0]OutputFinal;
wire Finished;

localparam PERIOD = 100;

always
	#(PERIOD/2) clk = ~clk;

initial begin
	#0 //starting the tanh 
	clk = 1'b1;
	reset = 1'b1;
	// trying a random input(0.600000023842)     where tanh(0.600000023842)=0.53704958
	x=16'b0011100011001101;

	#(PERIOD/2)
	reset = 0;	
	
	#400
	// waiting for 4 clock cycles then checking the output with approx.(0.53685)
	if(OutputFinal==32'b00111111000010010110111101111011 && Finished==1'b1)begin 
	 $display("Result is Right [Not in convergence region]");	  
	  end
	  else begin 
	 $display("Result is Wrong");	 
	    end	 
	    //trying another input which will be in the convergence region(3)  the output will be converged to 1    and reseting the function again
	    x=16'b0100001000000000;
	    
		reset = 1'b1;
		#(PERIOD/2)
		reset=1'b0;
		#200
		// checking if the output is 1
		if(OutputFinal==32'b00111111100000000000000000000000)begin 
	 $display("Result is Right [ convergence region]");	  
	  end
	  else begin 
	 $display("Result is Wrong ");	 
	    end	
	$stop;
end

HyperBolicTangent16 UUT
(
  .x(x),
	.clk(clk),
	.reset(reset),
	.OutputFinal(OutputFinal),
	.Finished(Finished)	
);
endmodule

如图所示:

在这里插入图片描述

将tb_HyperBolicTangent16设置为顶层:

在这里插入图片描述
开始进行仿真,操作如下:

在这里插入图片描述

开始仿真,如图:

在这里插入图片描述

仿真波形,如图:

在这里插入图片描述

关闭仿真:

在这里插入图片描述

2.2 UsingTheTanh16

2.2.1 设计输入

创建UsingTheTanh16文件,如图:

在这里插入图片描述

双击打开,输入代码:

module UsingTheTanh16(x,clk,Output,resetExternal,FinishedTanh);
parameter DATA_WIDTH=16;
parameter nofinputs=7;// deterimining the no of inputs entering the function
input resetExternal;// controlling this layer
input  signed [nofinputs*DATA_WIDTH-1:0] x;
input clk;
output reg FinishedTanh;
reg reset;// for the inner tanh
output reg [nofinputs*DATA_WIDTH-1:0]Output;
wire [DATA_WIDTH-1:0]OutputTemp;
reg [7:0]counter=0;
wire Finished;
reg [7:0]i;
// the inner tanh taking inputs in 32 bits and then increment using the i operator
HyperBolicTangent16 TanhArray (x[DATA_WIDTH*i+:DATA_WIDTH],reset,clk,OutputTemp,Finished);
 
 
always@(posedge clk)
begin 
  counter=counter+1;
// if the external reset =1 then make everything to 0
if(resetExternal==1) begin reset=1;i=0;FinishedTanh=0; end
//checking if the tanh is not finished so continue your operation and low down the reset to continue
  else if(FinishedTanh==0) begin 
    if(reset==1)begin reset=0; end 
    // if it is finished then store the output of the tanh and increment the input forward
      else if (Finished==1)begin Output[DATA_WIDTH*i+:DATA_WIDTH]=OutputTemp;reset=1;i=i+1;end
// check if all the inputs are finished then the layer is OK
if(i==nofinputs)
  begin FinishedTanh=1;end
end 

end
endmodule 

如图所示:

在这里插入图片描述

2.2.2 分析与综合

将UsingTheTanh16设置为顶层:

在这里插入图片描述

关闭上次的分析文件:

在这里插入图片描述

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

在这里插入图片描述
分析后的设计,Vivado自动生成原理图,如图:

在这里插入图片描述
对设计进行综合,操作如图:

在这里插入图片描述

2.2.3 功能仿真

创建TestBench,操作如图所示:

在这里插入图片描述

双击打开,输入激励代码:

module tb_UsingTheTanh16();
reg clk, resetExternal;
reg [63:0]x;
wire [63:0]Output;
wire FinishedTanh;

localparam PERIOD = 100;

always
	#(PERIOD/2) clk = ~clk;

initial begin
	#0 //starting the tanh 
	clk = 1'b1;
	resetExternal = 1'b1;
	// trying a random input(0.6,3)     where tanh(0.600000023842)=0.53704958, tanh(3)~=1
	x=64'b00111111000110011001100110011010_01000000010000000000000000000000;

	#(PERIOD/2)
	resetExternal = 1'b0;	
	
	#800
	// waiting for The final output which will be (0.57,1)
	if(Output==64'b00111111000010010110111101111011_00111111100000000000000000000000 && FinishedTanh==1'b1)begin 
	 $display("Result is right (for the full array of inputs)");	  
	  end
	  else begin 
	 $display("Result is Wrong");	 
	    end	 
	$stop;
end

UsingTheTanh16 UUT
(
  .x(x),
	.clk(clk),
	.Output(Output),
	.resetExternal(resetExternal),	
	.FinishedTanh(FinishedTanh)	
);

endmodule

如图所示:

在这里插入图片描述

将tb_UsingTheTanh16文件设置为顶层:

在这里插入图片描述
开始进行仿真,操作如下:

在这里插入图片描述

开始仿真,如图:

在这里插入图片描述

仿真波形,如图:

在这里插入图片描述

2.3 IntegrationConv

2.3.1 设计输入

双击打开integrationConv文件,修改代码为:

module integrationConv (clk,reset,CNNinput,Conv,ConvOutput);

parameter DATA_WIDTH = 16;
parameter ImgInW = 32;
parameter ImgInH = 32;
parameter ConvOut = 28;
parameter Kernel = 5;
parameter DepthC = 6;


input clk, reset;
input [ImgInW*ImgInH*DATA_WIDTH-1:0] CNNinput;
input [Kernel*Kernel*DepthC*DATA_WIDTH-1:0] Conv;
output [ConvOut*ConvOut*DepthC*DATA_WIDTH-1:0] ConvOutput;

reg TanhReset;
wire TanhFlag;

wire [ConvOut*ConvOut*DepthC*DATA_WIDTH-1:0] Cout;
wire [ConvOut*ConvOut*DepthC*DATA_WIDTH-1:0] CoutTanH;

convLayerMulti C1
(
	.clk(clk),
	.reset(reset),
	.image(CNNinput),
	.filters(Conv),
	.outputConv(ConvOutput)
);
UsingTheTanh16
#(.nofinputs(ConvOut*ConvOut*DepthC))
Tanh1(
      .x(Cout),
      .clk(clk),
      .Output(CoutTanH),
      .resetExternal(TanhReset),
      .FinishedTanh(TanhFlag)
      );
endmodule

如图所示:

在这里插入图片描述

2.3.2 分析与综合

将integrationConv设置为顶层:

在这里插入图片描述

关闭上次的分析文件:

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

对设计进行综合,操作如图:

在这里插入图片描述

纪念一下,2022卡塔尔世界杯,阿根廷捧起大力神杯,梅西圆梦

在这里插入图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/101101.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jsp+ssm计算机毕业设计动物救助平台【附源码】

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JSPSSM mybatis Maven等等组成,B/S模式 Mave…

实训任务4:Hadoop综合操作

文章目录1. 启动Hadoop服务2. 创建文本文件3. 上传文本文件4. 显示文件内容5. 完成排序任务6. 计算最大利润和平均利润1. 启动Hadoop服务 在master虚拟机上执行命令:start-all.sh 2. 创建文本文件 在master虚拟机上创建本地文件students.txt 李晓文 女 20 张晓航 男…

【Redis集群专题】「集群技术三部曲」分析一下相关的Redis集群模式下的脑裂问题(问题篇)

技术格言 世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。 什么是脑裂 字面含义 首先,脑裂从字面上理解就是脑袋裂开了,就是思想分家了,就是有了两个山头,就是有…

电脑调用 iPhone 摄像头全过程(iVCam)

最近不是停课不停学吗,令人“深恶痛绝”的钉钉又进入了我们学生的生活。但是初中的网课相比小学的又增加了一个要求:全程摄像头拍摄。但是,我这笔记本没有摄像头啊!突然想起来好像手机的摄像头可以给电脑调用。话不多说&#xff0…

3D数学基础 学习笔记

左手坐标系:DX、3DMax 右手坐标系:OpenGL 世界坐标系、物体坐标系、摄像机坐标系 向量和点在数学上是等价的,向量是有大小和方向的有向线段,向量没有位置,只有大小和方向 向量运算: 零向量:…

【看源码】@Cacheable和@CacheEvict的原理, 批量key过期失效的原因分析

Cacheable和CacheEvict的坑, 批量key过期失效的原因分析前言测试代码源码put缓存时最终key的产生看不同情况下, 是否能匹配Evict过期缓存1. 没有入参没有指定key的情况2. 有入参的情况3. 配置了allEntries的情况总结补充前言 最近发现自己搭的一个项目返回的数据不太准确, 第一…

网工Python之路——Netmiko模块实验(思科)

小白网工的python之路 「Python 网络自动化」Netmiko 实验环境 我的实验环境是GNS3搭建拓扑图,用云桥接到在VMware Workstation 16运行的CentOS 7, CentOS 7上搭建好了python3.8, 所有交换机已经预配好了SSH服务,ssh登录账号为python&…

paddle

paddle预测库 git config --global http.postBuffer 1048576000 git clone --recursive https://github.com/PaddlePaddle/Paddle.git 修改CMakeLists.txt mkdir build cd buildcmake -DWITH_CONTRIBOFF -DWITH_MKLOFF -DWITH_MKLDNNOFF -DWITH_TESTINGOFF -DCMAKE_BUILD_TY…

DBCO-PEG-Ferrocene,Ferrocene-PEG-DBCO,DBCO偶联修饰二茂铁

DBCO-PEG-Ferrocene ,Ferrocene-PEG-DBCO,二苯并环辛炔-聚乙二醇-二茂铁,DBCO偶联修饰二茂铁产品规格: 1.CAS号:N/A 2.分子量MV:1000、2000、3400、5000、10000、20000等可按需进行定制 3.包装规格&#xf…

数据结构与算法_空间复杂度

同时间复杂度一样,空间复杂度也是数学的函数表达式。 空间复杂度不是程序占用了多少 bytes的空间,因为这个也没太大意义,所以空间复杂度算的是运行的过程中临时的、额外的变量的个数。 空间复杂度计算规则基本跟实践 复杂度类似&#xff0c…

Flutter For App——一个简单的豆瓣APP

一个简单的豆瓣APP效果视频功能简述功能第三方库接口简述底部导航栏效果图实现初始化BottomNavigationBarItembottomNavigationBar切换页面导致bottomNavigationBar子页面重绘Top250榜单效果图实现Widget树FutureBuilder异常ListView上拉加载电影详情效果图实现高斯模糊网络数据…

设计模式原则 - 单一职责原则(一)

单一职责原则一 官方定义基本介绍二 案例演示普通方式实现解决方案解决方案一解决方案案例分析解决方案二解决方案案例分析案例总结三 注意事项&细节四 如何遵守单一职责原则?一 官方定义 单一职责原则(Single Responsibility Principle, SRP&#x…

用Spark写入Mysql的特别注意事项

相信有部分刚入门的小伙伴对于spark写入Mysql的过程不太熟悉。特意写一篇文章讲一下这个注意事项,以免“上大当” 我们先看一个小伙伴写的一段spark写入mysql的代码 public static void trans(SparkSession spark,String pro_table, String pro_url, String pro_dr…

微服务框架 SpringCloud微服务架构 服务异步通讯 52 惰性队列 52.1 消息堆积问题

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 服务异步通讯 文章目录微服务框架服务异步通讯52 惰性队列52.1 消息堆积问题52.1.1 消息堆积问题52 惰性队列 52.1 消息堆积问题 52.1.1 消…

11基于主从博弈理论的共享储能与综合能源微网优化运行研究(MATLAB程序)

参考文献: 基于主从博弈理论的共享储能与综合能源微网优化运行研究——帅轩越(2022电网技术) 主要内容; 代码主要做的是基于主从博弈理论的共享储能与综合能源微网优化运行研究,首先介绍了系统运行框架,分析了系统内…

一文了解各种高精度室内定位技术

在消费需求和创新技术驱动下,可穿戴设备和物联网产品的发展驶入了快车道,GNSS定位功能在无人驾驶、智能设备、资产追踪等日趋智能化中广泛应用,而随着万物互联时代的到临,物联网技术围绕人员、资产的室内位置服务需求也愈加强烈。…

vue使用

目录 路由History模式打包页面空白 项目放根目录 -- 配置 项目放二级目录 -- 配置 路由History模式打包页面空白 项目放根目录 -- 配置 router > index.js 修改 base const router new VueRouter({mode: history,// base: process.env.BASE_URL,base: /,routes, }) ngi…

【Redis集群专题】「集群技术三部曲」介绍一下常用的Redis集群机制方案的原理和指南(入门篇)

集群化的方案 Redis的Sentinel解决了主从复制故障不能自动迁移的问题,但是主节点的写性能和存储能力依然是受到了Redis单机容量有限的限制,所以使用Redis集群去解决这个问题,将Redis的数据根据一定的规则分配到多台机器。 Redis集群方案 R…

【git】

目录第一章 简介 1.1 版本控制 1.1.1 本地版本控制1.1.2 集中式版本控制1.1.3 分布式版本控制 第二章 基础篇 2.1 下载代码 2.2 更新代码 2.2.1 清空本地未被跟踪内容2.2.2更新代码使之与库上同步 2.3 修改 2.3.1 Vim2.3.2 Sed2.3.3 Awk 2.4 查看状态 2.5 保存代…

通俗易懂的java设计模式(3)-观察者设计模式

什么是观察者设计模式 观察者模式主要应用在对象存在一对多关系的情况下,那么如果一个对象,依赖于另一个对象,那个被依赖的对象一旦被修改,依赖于他的那个对象也会被观察者所告知。 观察者模式又被称作为发布-订阅模式&#xff0c…