基于FPGA的神经网络加速设计(一)

系列文章目录

基于FPGA的神经网络加速设计(一)



一、FP16(半精度浮点数)介绍

半精度浮点数 FP16 = {sign,exponent,mantissa} sign = 1bit exponent = 5bit mantissa = 10bit
x=±1.a×2^b 指数位是上述公式中的b加上偏置值,一般为2^(k−1)−1,其中k表示指数位的位数,尾数位是上述公式中的a
指数部分,5个比特位, 全0和全1有特殊用途,所以是00001~11110, 也就是1到30, 减去偏置15,指数部分最终范围为-14 ~15

二、FP16乘法器

1.设计代码及思路

代码如下(示例):

`timescale 100 ns / 10 ps

module floatMult (floatA,floatB,product);

input [15:0] floatA, floatB;
output reg [15:0] product;

 
reg sign;//符号位
reg signed [5:0] exponent; //指数位 多一位符号位
reg [9:0] mantissa;//尾数位
reg [10:0] fractionA, fractionB;	//fraction = {1,mantissa} 表示负数
reg [21:0] fraction;


always @ (floatA or floatB) begin
	if (floatA == 0 || floatB == 0) begin
		product = 0;
	end else begin
		sign = floatA[15] ^ floatB[15];//最高位异或,符号位相同返回0,即结果是正数;符号位不同返回1,即结果是负数
		exponent = floatA[14:10] + floatB[14:10] - 5'd15 + 5'd2;//加2是为了让其变量都变成小数类似于 0.1*10^10
	
		fractionA = {1'b1,floatA[9:0]};
		fractionB = {1'b1,floatB[9:0]} ;
		fraction = fractionA * fractionB;
		//判断第一个‘1’出现的位置,根据不同的位置,移动小数点位置
		if (fraction[21] == 1'b1) begin
			fraction = fraction << 1;
			exponent = exponent - 1; 
		end else if (fraction[20] == 1'b1) begin
			fraction = fraction << 2;
			exponent = exponent - 2;
		end else if (fraction[19] == 1'b1) begin
			fraction = fraction << 3;
			exponent = exponent - 3;
		end else if (fraction[18] == 1'b1) begin
			fraction = fraction << 4;
			exponent = exponent - 4;
		end else if (fraction[17] == 1'b1) begin
			fraction = fraction << 5;
			exponent = exponent - 5;
		end else if (fraction[16] == 1'b1) begin
			fraction = fraction << 6;
			exponent = exponent - 6;
		end else if (fraction[15] == 1'b1) begin
			fraction = fraction << 7;
			exponent = exponent - 7;
		end else if (fraction[14] == 1'b1) begin
			fraction = fraction << 8;
			exponent = exponent - 8;
		end else if (fraction[13] == 1'b1) begin
			fraction = fraction << 9;
			exponent = exponent - 9;
		end else if (fraction[12] == 1'b1) begin
			fraction = fraction << 10;
			exponent = exponent - 10;
		end else if (fraction[11] == 1'b1)begin
			fraction = fraction << 11;
			exponent = exponent - 11;
		end else begin
			fraction = fraction << 12;
			exponent = exponent - 12;
		end
		mantissa = fraction[21:12];
		if(exponent[5]==1'b1) begin //exponent is negative
			product=16'b0000000000000000;
		end
		else begin
			product = {sign,exponent[4:0],mantissa};
		end
	end
end

endmodule

2.仿真代码

`timescale 100 ns / 10 ps

module floatMult_TB ();

reg [15:0] floatA;
reg [15:0] floatB;
wire [15:0] product;

initial begin
	
	// 4 * 5
	#0
	floatA = 16'b0100010000000000;
	floatB = 16'b0100010100000000;

	// 0.0004125 * 0
	#10
	floatA = 16'b0111010011100010;
	floatB = 16'b0000000000000010;

	#10
	$stop;
end

floatMult FM
(
	.floatA(floatA),
	.floatB(floatB),
	.product(product)
);

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值