当前位置: 首页 > news >正文

fpga系列 HDL:全连接层的浮点数乘法器FM实现

  • 此代码实现了一个简单的浮点数乘法器,处理两个32位的单精度浮点数。它通过将两个浮点数的有效数字部分进行乘法操作,并对结果进行规范化以生成最终的浮点乘积。

主要逻辑与电路

  • 去掉指数对齐部分后的主要逻辑电路图示:
    在这里插入图片描述

代码

// https://github.com/omarelhedaby/CNN-FPGA/blob/master/CNN-FPGA-Vivado/CNN-FPGA-Vivado.srcs/sources_1/imports/Integration%20first%20part/floatMult.v
module floatMult (floatA,floatB,product);input [31:0] floatA, floatB;
output reg [31:0] product;reg sign;
reg [7:0] exponent;
reg [22:0] mantissa;
reg [23:0] fractionA, fractionB;	//fraction = {1,mantissa}
reg [47:0] fraction;always @ (floatA or floatB) beginif (floatA == 0 || floatB == 0) beginproduct = 0;end else beginsign = floatA[31] ^ floatB[31]; // 通过异或操作计算结果的符号位exponent = floatA[30:23] + floatB[30:23] - 8'd127 + 8'd2; // 计算结果的指数部分。首先加上两个输入的指数部分,然后减去偏移量127,并加2(因为在乘法中指数的偏移量增加了)。fractionA = {1'b1,floatA[22:0]};fractionB = {1'b1,floatB[22:0]};fraction = fractionA * fractionB;// 规范化结果,调整指数exponent和有效数字fraction以保持数值的正确性if (fraction[47] == 1'b1) begin // 找出第一个一开头的“1”fraction = fraction << 1;exponent = exponent - 1; end else if (fraction[46] == 1'b1) beginfraction = fraction << 2;exponent = exponent - 2;end else if (fraction[45] == 1'b1) beginfraction = fraction << 3;exponent = exponent - 3;end else if (fraction[44] == 1'b1) beginfraction = fraction << 4;exponent = exponent - 4;end else if (fraction[43] == 1'b1) beginfraction = fraction << 5;exponent = exponent - 5;end else if (fraction[42] == 1'b1) beginfraction = fraction << 6;exponent = exponent - 6;end else if (fraction[41] == 1'b1) beginfraction = fraction << 7;exponent = exponent - 7;end else if (fraction[40] == 1'b1) beginfraction = fraction << 8;exponent = exponent - 8;end else if (fraction[39] == 1'b1) beginfraction = fraction << 9;exponent = exponent - 9;end else if (fraction[38] == 1'b0) beginfraction = fraction << 10;exponent = exponent - 10;end else if (fraction[37] == 1'b1) beginfraction = fraction << 11;exponent = exponent - 11;end else if (fraction[36] == 1'b1) beginfraction = fraction << 12;exponent = exponent - 12;end else if (fraction[35] == 1'b1) beginfraction = fraction << 13;exponent = exponent - 13;end else if (fraction[34] == 1'b1) beginfraction = fraction << 14;exponent = exponent - 14;end else if (fraction[33] == 1'b1) beginfraction = fraction << 15;exponent = exponent - 15;end else if (fraction[32] == 1'b1) beginfraction = fraction << 16;exponent = exponent - 16;end else if (fraction[31] == 1'b1) beginfraction = fraction << 17;exponent = exponent - 17;end else if (fraction[30] == 1'b1) beginfraction = fraction << 18;exponent = exponent - 18;end else if (fraction[29] == 1'b0) beginfraction = fraction << 19;exponent = exponent - 19;end else if (fraction[28] == 1'b1) beginfraction = fraction << 20;exponent = exponent - 20;end else if (fraction[27] == 1'b1) beginfraction = fraction << 21;exponent = exponent - 21;end else if (fraction[26] == 1'b1) beginfraction = fraction << 22;exponent = exponent - 22;end else if (fraction[27] == 1'b1) beginfraction = fraction << 23;exponent = exponent - 23;endmantissa = fraction[47:25];product = {sign,exponent,mantissa};end
endendmodule

32 位 float 型的二进制存储

32 位 f l o a t 型数 V = ( − 1 ) S ∗ M ∗ 2 E 32 位 float 型数V=(-1)^S*M*2^E 32float型数V=(1)SM2E

Layer 1 22 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 23 30 31 指数位E 符号位S 有效数字M(实际计算时会包含前边的“1”,存储时省略“1”) (-1)^S*M*2^E

语句fraction = fractionA * fractionB;

        fractionA = {1'b1, floatA[22:0]};fractionB = {1'b1, floatB[22:0]};fraction = fractionA * fractionB;
  • fractionAfractionB 将浮点数的有效数字部分扩展到24位(包括隐含的1位)。
  • fractionfractionAfractionB 的乘积结果,占48位。
  • 示例计算过程,实际计算没有点号:
        fractionA = {1'b1, floatA[2:0]};fractionB = {1'b1, floatB[2:0]};fraction = fractionA * fractionB;
Layer 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1

语句exponent = floatA[30:23] + floatB[30:23] - 8’d127 + 8’d2;

其中- 8’d127的作用

  • floatA[30:23] 和 floatB[30:23] 表示从30位到23位的位值,即分别取浮点数floatA和floatB的指数部分。在IEEE 754单精度浮点格式中,这8位代表了带有偏移量的指数值(即真实指数加上127得到的值)。- 8’d127 这里的8’d127表示一个8位的二进制数,值为127,这是用来去除指数的偏移量。在浮点数中,为了能表示负的指数值,实际的指数是存储的指数值减去一个固定的偏移量,在单精度模式下该偏移量为127。

其中+ 8’d2的作用

  • 8’d2 在计算完两个数的指数之和后,再加上2。这一步骤可能是为了补偿乘法过程中指数的变化。方便后续代码的统一编写。如1.101*1.011=10.001111
    变为浮点数表示的有效数字,除去第一位的1( fraction = fraction << 1; ),变为0001111(表示.0001111,实际上为0.001111),所以表示成实际上的值还需要*2^(1)
    写成代码就是
exponent = floatA[30:23] + floatB[30:23] - 8'd127; if (fraction[47] == 1'b1) begin fraction = fraction << 1;exponent = exponent + 1; 

这里+2后,在处理规格化问题时就能统一成如下代码:

exponent = floatA[30:23] + floatB[30:23] - 8'd127 + 8'd2; if (fraction[47] == 1'b1) begin fraction = fraction << 1;exponent = exponent - 1; 

生成输出

        mantissa = fraction[47:25];product = {sign, exponent, mantissa};
  • mantissafraction 的高24位作为有效数字部分。
  • 最终输出 productsign(符号位)、exponent(指数部分)和 mantissa(有效数字部分)组成。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • maya的重命名物体和材质工具(带ai过程)
  • 机器学习 vs 深度学习:深入浅出解析两者的区别
  • 【Java基础】String详解
  • overleaf如何引用文献
  • 时序预测 | Matlab实现SSA-TCN麻雀搜索算法优化时间卷积网络时序预测-递归预测未来数据(单输入单输出)
  • 【每日刷题】Day123
  • Java 21的Enhanced Deprecation的笔记
  • Android生成Java AIDL
  • URL.createObjectURL 与 FileReader:Web 文件处理两大法宝的对比
  • AI客服机器人开启企业客户服务新纪元
  • 『功能项目』眩晕图标显示【52】
  • 『功能项目』怪物的有限状态机【42】
  • 语言的枚举
  • Python编程 - 异常处理与文件读写
  • Rust编写Windows服务
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • CSS魔法堂:Absolute Positioning就这个样
  • express.js的介绍及使用
  • Linux链接文件
  • scrapy学习之路4(itemloder的使用)
  • SegmentFault 2015 Top Rank
  • Shell编程
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从0实现一个tiny react(三)生命周期
  • 汉诺塔算法
  • 技术胖1-4季视频复习— (看视频笔记)
  • 排序(1):冒泡排序
  • 浅谈web中前端模板引擎的使用
  • 微信小程序--------语音识别(前端自己也能玩)
  • 源码安装memcached和php memcache扩展
  • mysql面试题分组并合并列
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • #### go map 底层结构 ####
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #define用法
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (六)Hibernate的二级缓存
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一) storm的集群安装与配置
  • (转)视频码率,帧率和分辨率的联系与区别
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • ***通过什么方式***网吧
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .gitignore文件忽略的内容不生效问题解决
  • .net 7 上传文件踩坑
  • .net core Swagger 过滤部分Api
  • .NET Core 成都线下面基会拉开序幕
  • .net core 使用js,.net core 使用javascript,在.net core项目中怎么使用javascript
  • @RequestMapping处理请求异常