以下内容摘自《步步惊芯——软核处理器内部设计分析》一书
串行乘法
OR1200中串行乘法采用的是“移位——加”迭代算法,这种算法借鉴了手工计算乘法的过程,对于二进制乘法,比如:1101*1011,手工计算过程如图8.1所示。
图8.1 手工计算二进制乘法的过程
从图中可知手工计算时会将被乘数与乘数中每一位依次相乘,最后将所有的乘积项一并相加。这种方法速度快,但是用硬件实现时,会耗费较多硬件资源。“移位——加”迭代算法对此作了修改:每算出一乘积项,就加到乘积中。假设一开始B等于被乘数的值,A等于乘数的值,中间步骤算出的乘积项称为部分积,保存在D中,那么“移位——加”迭代算法的硬件结构图、运算过程分别如图8.2中(1)、(2)所示。
图8.2 “移位——加”迭代算法的结构图、运算过程
计算步骤如下:
(1)初始化B为被乘数,A为乘数,D为0,进位标志C为0。
(2)判断A[0]是否为1,如果A[0]为1,则D加上B,反之D加上0,无论A[0]为何值,都会将加法结果保存到D中,进位保存到C中。
(3)判断此时的A[0]是否是乘数的最高位,如果是,则将C、D、A联合右移一位,乘法结束,D、A联合起来就是积,反之也将C、D、A联合右移一位,回到第(2)步继续运行。
还是以1101*1011为例,采用“移位——加”迭代算法时计算步骤如表8.1所示。
“移位——加”迭代算法需要的时间与操作数的位数有关,对于32位的OR1200处理器而言,如果采用“移位——加”迭代算法实现乘法运算,那么至少需要32个时钟周期才能得到乘法结果。
并行乘法
串行乘法牺牲了处理器的效率,如果追求高效率的乘法运算,那么可以使用并行乘法,OR1200中实现并行乘法有两种方法。
1、利用FPGA内部的乘法器
利用FPGA内部的嵌入式乘法器,直接实现乘法,在OR1200中如果使用并行乘法,那么乘法的代码实际很简单,如下:
or1200_gmultp2_32x32.v always @(posedge CLK or `OR1200_RST_EVENT RST) if (RST == `OR1200_RST_VALUE) p0 <= `OR1200_WW‘b0; else p0 <= xi * yi; //直接就是xi*yi
当选中了目标FPGA时,EDA综合工具会自动调用目标FPGA内部的乘法器实现乘法运算。笔者使用Altera的EP2C70作为目标芯片,经过QuartusII编译后,可以发现乘法器的使用情况如图8.3所示,从图中可知为了实现32位的乘法运算,最终使用了4个18x18的嵌入式乘法器。
图8.3 QuartusII编译后显示采用并行乘法时,OR1200共使用了4个18x18嵌入式乘法器
2、Booth算法
如果是ASIC设计,则并行算法采用的是Booth算法,本书不对ASIC设计做过多着墨,读者朋友可以直接通过互联网查找Booth算法的介绍。
通过本章后面的分析可以知道:如果OR1200采用并行乘法,那么乘法运算需要5个时钟周期。