关于乘法器的那些事

一、整数乘法器

1.1 整数的概念

整数在IEEE的规定上有,短整数 short integer ,中整数 integer 和 长整数 long integer ,他们之间的关系如下:

整数 字节空间 取值范围
短整数 一个字节 -127 ~ 127
整数 二个字节 -32767~32767
长整数 四个字节 -2147483647~2147483647

若无特殊说明,以下都以短整数举例。

四个结论:

  • 短整数的最高位是符号位,正值的符号位是“0”,负值的符号位是“1”。
  • 正值用原码表示,负值用补码表示。
  • 正值(8’b0000_0100)“取反加一”就得到负值(8’b1111_1100) ; 同理,负值(8’b1111_1100)“取反加一”就得到正值(b’b0000_0100)。
  • 8’b1000_0000既不是正数也不是负数也不是0,它是划分正值和负值的边界线。
1
2
3
4
5
+4   即 8'b0000_0100;
+127 即 8'b0111_1111;
分界线 8'b1000_0000;
-127 即 8'b1000_0001;
-4 即 8'b1111_1100;

1.2 传统乘法器

在传统概念上,乘法等价于“重复几次”,也就是累加操作。比如:B=4,那么A x B等价于A重复加四次。那如果B=-4应该怎么理解呢?
先来看一组例子:

1
2
3
4
5
A x B = C;
3 x 4 = 12;
-3x 4 = -12;
3 x-4 = -12;
-3x-4 = 12;

其中,C的值可以看成由两部分构成:正负和数值。

撇开正负不看,乘积的数值就是A和B绝对值相乘的结果。那么乘积的正负如何确定呢?

其实正负号的运算规则和数字电路中的“异或运算”一样。

A B C(A⊕B)
0 0 0
0 1 1
1 0 1
1 1 0

其中,0表示正号,1表示负号。

因此,传统乘法器实现的大致操作如下:

  1. 在初始化之际,取乘数和被乘数的正负关系,然后取乘数和被乘数的正值。
  2. 每一次累加操作,递减一次乘数。直到乘数的值为零,表示操作结束。
  3. 输出结果根据正负关系取得。

其实传统的乘法器是很容易的,但是随着整数的出现,负值和正值也随着出现,这也使得设计多了一点难度。但是只要掌握负值和正值的关系以后,乘法只作正值也“无问题” ,只要在结果输出之前“下一点手脚”就行了。

1.3 传统乘法器的改进

传统的乘法器虽然简单,但是它有一个致命的问题。就是被乘数越大就越消耗时钟。那么要解决这个问题就要了解为什么会产生这个问题。还是举例来说:

假设A=10 , B=20 , A x B ,那么时钟的消耗至少需要 20个,因为A值需要累加20次才能得到结果。回顾一下乘法法则:A x B = B x A。如果以B作为基础,那么B值只需要累加10次就能得到结果,这样就可以节省时钟的消耗。

因此我们可以这样改进:在进行累加操作之前,增加一个比较步骤。如果被乘数小于乘数,那么被乘数和乘数互换。

1
{Multiplier , Multiplicand} = Multiplicand < Multiplier ? {Multiplicand ,Multiplier} : {Multiplier ,Multiplicand};

于是,改进版传统乘法器实现的大致操作如下:

  1. 在初始化之际,取乘数和被乘数的正负关系,然后取被乘数和乘数的正值。
  2. 乘数和被乘数比较,如果被乘数小于乘数,结果乘数和被乘数互换。
  3. 每一次累加操作,递减一次乘数。直到乘数的值为零,表示操作结束。
  4. 输出结果根据正负关系取得。

传统的乘法器无论如何改进也好,当遇见如 127 x 127 的乘数和被乘数,咋样也看不出什么可以优化的地方…

1.4 补码的意义

上面也说到过一点,就是实现正数和负数之间的转换,也就是说使符号位能与有效值部分一起参加运算,从而简化运算规则。

另外,还有一点就是使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。

1.5 Booth算法乘法器


未完待续。。。

坚持原创技术分享,您的支持将鼓励我继续创作!
显示 Gitment 评论