分享

verilog无符号数和有符号数相加问题

 独孤琅嬛 2014-05-06

今天逛论坛碰到一个问题:

一个8位的无符号数a和一个8位的有符号数b相加,应该是准备一个9位的寄存器来接收结果还是应该准备一个10位的寄存器来接受结果?

楼下的有说应该用10位的,也有说用9位的,那么到底用几位的,我个人感觉都可以,但是用10位的更好一些,下面来分析。

首先,如果那个无符号的8位数a大到极限,就是1111_1111,即255,小到极限就是0000_0000=0;再看那个有符号的8位数b,大到极限0111_1111=127,让他小到极限1000_0000=-128(这里注意小到极限不是1111_1111,他是-127,还有个负零呢)。所以a+b的范围就是[0-128=-128,255+127=382]。

如果用9位数来接,那就首先要判断结果是大于零还是小于零,如果结果>0,那么这个9位数要以无符号数的身份来接收结果,即最高位[9]是数据位,以防止结果位于[255,382]时不会丢失数据。如果结果<0,那么这个9位数就要以有符号数的身份来接收结果,即最高位[9]是符号位,以防止结果成为真实值得相反数。

如果用10位数来接,那么可以直接把最高位[10]定为符号位,这样,如果结果大于零,则[10]=0,如果结果小于零,则[10]=1,而其余9位可以直接作为数据位,这样显然比用9位接方便得多。

所以,题干中的加法最好是将a、b都扩展到10位并全都转换为有符号数,然后再相加。

无符号数要扩展符号位到有符号数 所以 wire [8:0] signed_a={1'b0,a};
有符号数要本身最高位即是符号位 但是两数相加 所以 wire [8:0] expand_b = {b[7], b};
wire [9:0] c_tmp = {signed_a[8],signed_a} + {expand_b[8],expand_b};

有网友经过仿真得到最终结论:

 仿真过后,得先扩展到十位,再相加。扩展到九位相加得不到正确的结果。扩展方法:
wire [9:0]                  s_data_a = {2'b0,data_a};
wire [9:0]                  s_data_b = {{2{data_b[7]}},data_b};
无符号数,高位补零,有符号数,复制最高位符号位。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多