Verilog实现二进制有符号定点数的乘法运算

二进制运算原理

总结最近FPGA的学习,使我明白了一件事:在Verilog程序的编写中,“位”(bit)这一概念,对于程序编写至关重要,Verilog代码中,数据运算均以位来操作,因此我觉得有必要认真研习一下二进制运算的基本过程和运算方法。
有符号二进制数的表示一般以二进制补码(two’s-complement)的形式来表示,有助于我们理解和编写底层二进制运算的程序。相信这对我们单片机和FPGA的学习将收益匪浅。

1、无符号二进制数(unsigned)乘法运算

1.1 无符号数常规运算

对于无符号数的乘法运算相对简单,直接通过移位后相加得到。这里我随意举个无符号数相乘的例子来说明运算法则,比如(1001)2 和(0101)2 相乘可以写成如下形式:
1001和0101相乘
从上式可以看出,该运算和我们十进制的运算相差无几,在二进制运算中乘数(0101)从低位开始与被乘数(1001)相乘。在乘数为1时就相当于对被乘数进行相应的移位操作,乘数使用的是第n位,则被乘数相应的右移(n-1)位,最后对中间结果进行相加,得到运算结果。
原理相当简单,但是在verilog代码编写中,在规定了乘数与被乘数的数据位宽后(如例子的4bits数据),结果数据位宽范围:4bits~7bits(4+4-1),为防止运算结果溢出则需要预先给结果数据给定7bits的位宽。
根据最近的Verilog的学习,我总结了如下表的数据位宽分配规律(当然是针对无符号数而言)

数据名 数据位宽
乘数 a
被乘数 b
乘积 a+b-1

1.2 无符号数乘法补位运算

同时,在最近《深入理解计算机系统》一书的阅读中,我理解了另一种无符号二进制数的运算方法。是一种补位的方式,在已知乘数和被乘数的位宽后,对其进行相同于乘积位宽的补位,高位补0,一直到所定义的乘积的最高位,这里我定义乘积数据的位宽为8bits,对于高于所定义位宽的数据进行截断并舍弃。形式如下图所示:
在这里插入图片描述
当然补位方法是一种通用与有符号和无符号数的运算方法,对于无符号数的运算优势可能不突出,但是对于有符号的运算优势则极其突出。

2、有符号二进制数(signed)乘法运算

2.1 有符号定点数乘法运算

有符号二进制数则和第1节中的无符号数运算过程有些差异,在之前的学习中我参考了一篇博客园中搬运翻译的博客:

符号定点二进制小数(Qn format)乘法原理:https://www.cnblogs.com/Yuya-memeda/p/12708868.html
原博客(Fixed-Point Representation: The Q Format and Addition Examples):https://www.allaboutcircuits.com/technical-articles/fixed-point-representation-the-q-format-and-addition-examples/

运算过程分成了4种:正数 * 正数;正数 * 负数; 负数 * 正数 以及 负数 * 负数。不同的情况对应不同的运算法则,感兴趣可以去看看过程,相信会有帮助。
在这里我就不做重复的劳动了,我这里主要要记录的是第二种方法。

2.2 有符号定点数乘法补位运算

该方法相比2.1节中对有符号定点数,需要分四种情况进行运算的方法会相对简单得多。
此方法和1.2节中的补位运算相同,对于有符号数的乘法运算,对其乘数和被乘数进行位宽扩展。
这里我总结了一下,扩展后的位数宽度为正常乘积位数 + 符号位,即:

扩 展 后 位 宽 = 被 乘 数 位 数 a + 乘 数 位 宽 b − 1 + 符 号 位 宽 ( 1 b i t ) = a + b 扩展后位宽=被乘数位数a + 乘数位宽b -1 + 符号位宽(1bit)=a+b =a+b1+1bit=a+b
扩展时,对高位进行补充的方式和无符号数的运算不一样,需要依据符号进行补充,符号位为‘1’则高位补‘1’,符号位为‘0’则高位补‘0’。同样的以(1001)2和(0101)2 为例。乘数与被乘数均是4bits,扩展后不至于溢出的位数为4+4=8bits
有符号数是以补码(正数的补码为其本身,负数的补码为其反码+1)的形式来表示的,则该数据的结果为:

补 码 : 1001 = > 反 码 : 0110 = > 原 码 : 0111 ( − 7 ) 补码:1001 =>反码:0110=>原码:0111 (-7) 1001=>0110=>01117

补 码 : 0101 = > 原 码 : 0101 ( 5 ) 补码:0101 =>原码:0101 (5) 0101=>01015

乘 法 运 算 : − 7 ∗ 5 = − 35 乘法运算:-7*5 = -35 75=35

应用补位截断的方法进行有符号定点数乘法如下图所示
在这里插入图片描述

高于扩展位数的数据进行截断舍弃,最后结果如下

补 码 : 11011101 = > 反 码 : 00100010 = > 原 码 : 00100011 补码:11011101&#

  • 55
    点赞
  • 299
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值