FPGA基本算术运算

news2024/10/6 4:12:27

FPGA基本算术运算

  • FPGA基本算术运算
    • 1 有符号数与无符号数
    • 2 浮点数及定点数
      • I、定点数的加减法
      • II、定点数的乘除法
    • 3 仿真验证
      • i、加减法验证
      • ii、乘除法验证

FPGA基本算术运算

  FPGA相对于MCU有并行计算、算法效率较高等优势,但同样由于没有成型的FPU等MCU内含的浮点数运算模块,导致一些基本的符号数、浮点数运算需要我们自己进行管理。因此需要我们对基本的运算法则进行了解。基本类别如下,即:

在这里插入图片描述

1 有符号数与无符号数

   无符号数即为没有符号的数,简单点就是全部为正数运算的数没有负数。有符号数字便是有正与负数的数。那么在同样位数的条件下,表示的有符号数范围更加少,如下。

reg [7:0] unsigned_a; //定义一个无符号8位数 
					//既然无符号,则可表示 0 - 0xFF,即 0 -255;
					//256 - 0x100 即超出了8位

  以上是无符号数的概念,而有符号数则为了表示符号,将补码的概念引入了基本数体系,建立了符号数体系

符号体系中,补码即将数分为符号位和基本数位;最高位表示符号位,1为负,0为正数,其他基本数位则表示正常数码。

reg signed [7:0] sign_b; //8位有符号数 bit7:符号位; bit6-bit0: 数位
						 //此时数位,最大只能表示0-127,较8位无符号数可表示范围减少一半
					 

  同时,为了方便运算减法,建立了补码运算体系,即a-b可转换为 a + b[补码]。

​ 因此,定义,正数的原码、反码、补码均相同,负数原码、反码、补码经过以下运算得到:

//正数:8’d82 - 8'b0101_0010
//原码:8'b0101_0010
//反码:8'b0101_0010
//补码:8'b0101_0010

//负数: -8’d82 
//原码:8'b0101_0010
//反码:8'b1010_1101 (原码取反)
//补码:8'b1010_1110 (反码 + 1)

//8位有符号数:
//正数:  8’d127 补码: 8'hff
//....
//正数:  8’d2  补码: 8'h02
//正数:  8’d1  补码: 8'h01
//      8'd0   补码: 8'd0
//负数: -8’d1  补码: 8'hff
//负数: -8’d2  补码: 8'hfe
// ...
//负数: -8’d127  补码: 8'h81

  根据以上规则,发现0是个特殊的数字,+0的补码即是8‘h0,而-0的补码是8’h80,而0 仅仅就是0。于是一般规定,8’h80为-128。因此8位有符号数范围为[-128,127],相对于无符号数[0,255],数值大小降低了一半。

2 浮点数及定点数

  浮点数主要是遵守 IEEE754 浮点数标准这里不再缀述。而定点数,即是固定小数点的一种方式,如

//十进制小数: 32.15 - 二进制:100000.00100110011001100110011001100110011001100110011
//保留10位二进制小数后 - 100000.0010011001 (32.1494140625) - 有截断误差
//定义定点数为Q10     - 即将原来的数乘以2^10 - 1000000010011001(32921)
//Qn  表示小数点在第几位前面

I、定点数的加减法

  不同定点数的加减要转换为同一定点格式才能相加减,即

//32.15 - 32921(Q10)
//15.62 - 7997(Q9)
//32.15 + 15.62 = 47.77
// 32921 + 7997* 2^(10-9) = 48915(Q10)
// 48915/ 2^10 = 47.7685546875 [有截断误差]

  Qm的定点数 +(-) Qn位的定点数{m>n},需要将n位数定点扩展到同一位置,然后进行运算,结果为Qm。

  因此m位的定点数 +(-) n位的定点数,首先需要将结果变量扩展到m+1位(防止溢出)

II、定点数的乘除法

//32.15 - 32921(Q10)
//15.62 - 7997(Q9)
//32.15 * 15.62 = 502.183
// 32921 * 7997 = 263269237(Q19)
// 263269237/ 2^19 = 502.1462192535400390625 [有截断误差]

 Qm的定点数 *(/) Qn位的定点数{m>n},结果为Q(m+n)。

  因此m位的定点数 *(/) n位的定点数,首先需要将结果变量扩展到m+n位(防止溢出)

3 仿真验证

i、加减法验证

对如下module进行激励测试:

module add(

	input [7:0] a,
	input [7:0] b,
	
	output [7:0] c

);

wire [8:0] add_out;
wire [8:0] sub_out;

wire [7:0] add_out_2;
wire [7:0] sub_out_2;

assign add_out = a+b;
assign sub_out = a-b;

assign add_out_2 = a+b;
assign sub_out_2 = a-b;

endmodule

第一阶段,a->8’d12; a->8’d35。

在这里插入图片描述

可以看到8位及9位的结果输出均正常,这时12-35=-23的结果自动变为补码。

第二阶段,a->-8’d12; a->8’d35。

在这里插入图片描述

第二阶段这里就发现了9位的输出结果明显不对,这里0xf4(-12) + 0x23 = 0x117;结果溢出了。正常情况,有符号数符号位不会参与运算,这里参与了运算导致了错误[主要是结果溢出导致]

有两种办法进行修改:

1)将input 改为:

​ input signed [7:0] a,
​ input signed [7:0] b,

2)将加法运算进行扩展后计算

​ assign add_out = {a[7],a} + {b[7],b}; //扩展符号位
​ assign sub_out = {a[7],a} - {b[7],b};

结论:对于是否定义有无符号数,即使是无符号数,运算产生负数后,也会使用补码进行表示。但是如果计算结果存在溢出,则会产生错误,所以即使不使用signed类型也可,但需要注意位宽。

ii、乘除法验证

module chengc(

	input [7:0] c1,
	input [7:0] c2,
	
	output [7:0] d2

);

wire [15:0] mux_out;
wire [15:0] divid_out;

wire [7:0] mux_out_2;
wire [7:0] divid_out_2;


assign mux_out	 = c1 * c2;
assign divid_out = c1 / c2;

assign mux_out_2   = c1 * c2;
assign divid_out_2 = c1 / c2;



endmodule

与加减法相似,在溢出时,仍旧出现了符号位参与运算导致的错误。

在这里插入图片描述

这个时候进行如下修改:

module chengc(

	input signed [7:0] c1,
	input signed [7:0] c2,
	
	output [7:0] d2

);

wire signed [15:0] mux_out;
wire signed [15:0] divid_out;

wire [15:0] mux_out_2;
wire [15:0] divid_out_2;


assign mux_out	 = ({ {8{c1[7]}},c1}) * ( { {8{c2[7]}}, c2});
assign divid_out = ({ {8{c1[7]}},c1}) / ( { {8{c2[7]}}, c2});


assign mux_out_2   = c1 * c2;
assign divid_out_2 = c1 / c2;



endmodule

此时输出结果如下:

在这里插入图片描述

在除法运算中,符号位仍旧参与了运算,导致结果失常。因此这里并不推荐直接使用 * / ,FPGA最好使用片上自带的DSP模块进行运算,也可使用移位及加减进行近似运算。如:

//a * 0.625 = a * (0.10011101011100001010001111010111000010100011110101111)b

//a * 1/2 + a*1/8 + a*1/16 + a*1/32 + ... +.. 进行近似运算

定点数乘除法,因已将定点数转为了整数,因此也可参考该过程。

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

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

相关文章

11 滑动窗口最大值

滑动窗口最大值 题解1 优先队列(大顶堆)(双循环没过)改进后 题解2 单调队列deque(设计同labuladong)标准题解(同接雨水,deque存下标) 题解1 优先队列(大顶堆&…

77 # koa 中间件的应用

调用 next() 表示执行下一个中间件 const Koa require("koa");const app new Koa();app.use(async (ctx, next) > {console.log(1);next();console.log(2); });app.use(async (ctx, next) > {console.log(3);next();console.log(4); });app.use(async (ctx,…

aardio语言简易中英单词翻译

import win.ui; /*DSG{{*/ mainForm win.form(text"简易中英文单词离线翻译";right757;bottom467;bgcolor15780518) mainForm.add( buttonWord{cls"button";text"翻译(CtrlS)";left121;top384;right279;bottom425;z3}; editFrom{cls"edit&…

官方项目《内容示例》中Common UI部分笔记:Common UI 分场景使用教程

文章目录 前言0. 通用设置0.1 开启插件0.2 设置Viewport 1. 分场景教程1. 1 在仅使用鼠标控制的场景下Common Activatable StackCommon Activatable Widget 1.2 当焦点落到一个按钮时显示默认确认(Click/Accept)按键图标Common Input Action DataBaseInp…

JVM--Hotspot Architecture 详解

一、Java Virtual Machine (JVM)概述 Java Virtual Machine 虚拟机 (JVM) 是一种抽象的计算机。JVM本身也是一个程序,但是对于编写在其中执行的程序来说,它看起来像一台机器。对于特定的操作系统&#xff…

docker介绍和安装

docker安装 下载Docker依赖组件 yum -y install yum-utils device-mapper-persistent-data lvm2 设置下载Docker的镜像源为阿里云 yum-config-manager --add-repo http://mirrors.aliyun.com/dockerce/linux/centos/docker-ce.repo 安装Docker服务 yum -y install docker-ce 安…

Python 3.x 异常处理

文章目录 异常处理1. 什么是异常2. Python 中的异常python 中异常演示错误类型捕获try-except 语句带有多个 expect 的 try 语句捕获未知错误 异常参数else 子句finally子句练习 3:简化除法判断 3. 自定义异常抛出异常—raise应用场景抛出异常练习 4:自定…

innovus:route within pin 和限制pin shape内via 数量

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 setNanoRouteMode -routeWithViaInPin "1:1" setNanoRouteMode -routeWithViaOnlyForStandardCellPin "1:1"

git 后悔药

前言 自上而下,撤销可以分为从远程库撤销,从本地库撤销,从暂存库撤销。 例子:代码已经提交了三个记录到远程库,分别对应了记录1,内容1,记录2,内容2,记录3,内…

LeetCode73.矩阵置零

这道题我感觉还是挺简单的,一下子就想到了,不过我的算法很简单很垃圾,效率很低,我一看完题的想法就是直接遍历一遍数组,然后把为0的元素的行和列都存起来,然后把这些行和列都置零就好了,但是这里…

IP地址、子网掩码、网络地址、广播地址、IP网段

文章目录 IP地址IP地址分类子网掩码网络地址广播地址IP网段 本文主要讨论iPv4地址。 IP地址 实际的 IP 地址是一串32 比特的数字,按照 8 比特(1 字节)为一组分成 4 组,分别用十进制表示然后再用圆点隔开,这就是我们平…

chkdsk H:/F

chkdsk H:/F TF卡损坏

nios里面打开eclipse遇到Unresolved inclusion: “system.h“等问题

问题:在Nios中打开软核部分代码时,遇到一堆Unresolved inclusion: "system.h"等问题报错 原因:bsp文件和软核没关联,导致找不到头文件地址,关联一下就好 解决步骤: 右键bsp文件,点击…

虚幻引擎集成web前端<一>:win环境UE4.27导出像素流并集成到vue2环境(附案例)

本案例附件:https://download.csdn.net/download/rexfow/88303544 第一部分:虚幻引擎导出像素流windows包 第1步:软件设置 -AudioMixer -PixelStreamingIPlocalhost -PixelStreamingPort8888 第2步:信令服务器设置 1、执行run_l…

2023移动软件开发实验6

2023年夏季《移动软件开发》实验报告 姓名和学号?本实验属于哪门课程?中国海洋大学23夏《移动软件开发》实验名称?实验6:推箱子博客地址?XXXXXXXGithub仓库地址?https://github.com/enfantsRichesDeprimes…

十三、MySQL(DQL)语句执行顺序

1、DQL语句执行顺序: (1)from来决定表 # where来指定查询的条件 (2)group by指定分组 # having指定分组之后的条件 (3)select查询要返回哪些字段 (4)order by根据字段内容&#…

7.0: Dubbo服务调用源码解析

课程内容 服务提供者处理请求流程解析服务消费发送请求流程解析服务提供者端线程模型解析服务消费者端线程模型解析1.服务提供者处理请求流程解析 processon链接:服务调用流程图| ProcessOn免费在线作图,在线流程图,在线思维导图 2. 服务消费端执行逻辑 MockClusterInvoker.in…

【大数据之Kafka】七、Kafka Broker之Kafka副本

1 副本基本信息 Kafka 副本可以提高数据可靠性。分为Leader 和 Follower;Kafka 生产者只会把数据发往 Leader,然后 Follower 找Leader 进行同步数据。   Kafka 默认副本 1 个,生产环境一般配置为 2 个,保证数据可靠性&#xff1…

SAP-PP:基础概念笔记-4(物料主数据视图)

文章目录 前言一、基本视图二、分类视图三、销售视图四、采购五、生产计划和执行视图六、总工厂数据/存储七、质量管理八、会计九、成本系统创建示例:创建一个齿轮物料的主数据事务代码:MM01,另一种方式spro->xxxx 总结 前言 物料主数据为许多组织创…

linux并发服务器 —— 项目实战(九)

阻塞/非阻塞、同步/异步 数据就绪 - 根据系统IO操作的就绪状态 阻塞 - 调用IO方法的线程进入阻塞状态(挂起) 非阻塞 - 不会改变线程的状态,通过返回值判断 数据读写 - 根据应用程序和内核的交互方式 同步 - 数据的读写需要应用层去读写 …