在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 25590|回复: 42

[求助] 关于补码的加法和乘法运算

[复制链接]
发表于 2011-5-31 21:44:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 larlyii 于 2011-5-31 22:14 编辑

小弟我最近被一个问题纠结好久,就是有符号,无符号数,原码补码之间的运算,比如举个例吧,-6和7,我去算它们之间的加法和乘法。
假设输入数据用8位2进制表示。

首先,-6的原码是10000110,补码是11111010;7的原码是00000111,补码同样(因为是正数)
加法:加出来有9位:100000001,如果我们只取低8位,就是00000001,为十进制的1,答案正确。但是好多书上写的代码都是把加法器的输出扩展了一位的,那就是说,这个数的十进制表示变成了-255,明显不对~

乘法:乘出来有11位:11011010110,直接取的话肯定不对,但是如果只取低8位的话是11010110(补码),即十进制的-42,就正确。但是一般为了避免溢出,我看好多书上都是把乘法器的输出位宽扩展成输入的2倍,那这样输出又和上面的加法同样的由于扩展位宽而出现的错误。

按照以上逻辑,岂不是我设计的模块的输出必须和输入有同样的位宽?但实际情况显然不是,不知这是怎么一回事?

现贴上ModelSim的图为证:

十进制

十进制
十进制的

二进制

二进制
二进制的
发表于 2011-5-31 22:45:34 | 显示全部楼层
教你一个方法,一个三位和一个4位的有符号数相加,将二者都变成5位的,就是将二者的高位复制,然后相加后结果去掉最高一位,就是结果
发表于 2011-5-31 22:46:39 | 显示全部楼层
有符号数的加法无视最高位(就是符号位)的溢出,即11111010+00000111=00000001。
   无符号数的加法,需要扩展以为,因为最高位可能溢出。
   乘法的话,应该是先对2个数的符号位异或,异或的结果作为输出结果的符号位,然后再将乘数和被乘数都正值化,相乘的结果再加上符号位,就是最终的结果了
 楼主| 发表于 2011-6-1 07:57:56 | 显示全部楼层
本帖最后由 larlyii 于 2011-6-1 08:06 编辑

回复 2# l7951247


    这个原理我知道,但按照这样的方法,我在用FPGA实现的2个数相加时,岂不是就要先把输入的数扩展1位,再通过加法器,然后再把最高位去掉?但我看一般的书上直接就把2个数相加了呀,没有在之前扩展1位。

我主要就是纠结用FPGA实现算术运算和原码补码理论的算术运算之间的联系和差异。因为FPGA根本不知道输入的数是原码或补码,它会直接按照无符号数的加法乘法去操作的。
 楼主| 发表于 2011-6-1 08:04:31 | 显示全部楼层
本帖最后由 larlyii 于 2011-6-1 08:07 编辑

回复 3# JD.WARLOCK


    你说的加法我懂了,但乘法,你的意思是原码相乘吧?就是符号位和数据位分别处理,所以我觉得原码的乘法更好操作,但是如果我本生FPGA输入的数据就是补码的话,我是不是要先变成原码,然后再按照你说的方法那样去做?但我看很多书上都直接就对输入的2个数相乘就完了,它也没说这个输入输出是补码原码,所以一直比较混乱。


通过仿真我推断出FPGA根本不知道输入的数是原码或补码,它会直接按照无符号数的加法乘法去操作的。
发表于 2011-6-1 09:07:59 | 显示全部楼层
如果想直接写加法进行有符号数的相加,则需要定义成有符号数类型,例如wire signed  [7:0]  a,b,c;
assign c=a+b;即使位宽不匹配也可以不用关心,综合工具会自动匹配;
如果定义成无符号数,即95语法的,则对有符号数的计算需要手动扩展符号位(即最高位,而不是扩展0)后再进行相加。初学者建议采用手动扩展符号位的方式实现。
发表于 2011-6-1 09:39:18 | 显示全部楼层
FPGA内的符号运算,你需要将你的数变成补码再进行运算。
对于两个八位相加,它是先将两个加数扩展为九位再相加。

我曾经也为这个纠结很久。
给你个文档。

带符号数的处理和易犯的错位.pdf

158.55 KB, 下载次数: 556 , 下载积分: 资产 -2 信元, 下载支出 2 信元

发表于 2011-6-1 09:52:32 | 显示全部楼层



我觉得FPGA内的加法器或者乘法器不需要知道输入是原码还是补码,但是你必须要清楚,然后你根据输入是原码还是补码来决定将加法器或者乘法器输出中的哪些位截取出来作为最终的结果,不知道说的清楚不
发表于 2011-6-1 09:52:58 | 显示全部楼层
上边这个文档里边说到 第一个例子里边就讲了  比如你的-6 +7 。先扩展为9位,然后进行相加,结果也是取九位,第十位溢出就不要了。就是结果。
 楼主| 发表于 2011-6-1 21:34:17 | 显示全部楼层
回复 6# justshuashua


    按照你的说法,比如我2个8位的有符号数相加,我需要先把它扩展成9位,然后如果加出来的数仍然是9位,就把这9位作为输出,如果加出来的数是10位,我就把最高位去掉,仍然是9位输出。
即:




  1. input [7:0]a, b;
  2. output [8:0]sum;
  3. assign a_extend = {a[7], a};
  4. assign b_extend = {b[7], b};
  5. assign sum = a_extend + b_extend;



复制代码


这样对吧??
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-23 10:32 , Processed in 0.024354 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表