首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Spartan3硬件乘法器使用详解(3)

Spartan3硬件乘法器使用详解(3)

前面已经介绍了Spartan3系列FPGA中硬件乘法器的用途、调用方法、结构特定等等,对Xilinx FPGA中基本的硬核乘法器有了初步的认识。接下来对它的一些具体使用方法做更深入的介绍。
1. 扩展乘法器
FPGA可以对每一位进行操作,这极大地方便了对乘法器的扩展。虽然一个基本的硬件乘法器只有18*18位,但是我们可以通过把一个较多位数的乘法操作分解为较小一级层次的乘法。一个以二进制数代表的位数较长的输入可以在它的任何一个数据位进行截断,并分别送入不同的两个硬件乘法器;其结果是相同的,只需要在运算时考虑MSB和它的符号就可以了。
图1给出了一个22*16位乘法器的实现原理框图。22位的输入A被分解为18位的有符号数和4位的无符号数(从LSB)开始计算,则两个独立的乘法操作也需要同时进行。一个乘法的结果是20位的有符号乘法,它由16位的输入B和分解出的A的4位无符号数相乘得到。另一个乘法的结果是34位的有符号乘法,它由16位的输入B和分解出的A的18位有符号数相乘得到。加法操作存储了两个乘法的累积和(注意到:第一个乘法操作的最小几位被加法器旁路了),并得到了最终的38位乘法结果。加法器自身只需要34位就够了,即需要占用17个slice。

图1 22*16位乘法器的实现
这种乘法器的扩展实现方法,可以根据性能的要求和可用的芯片资源来改变。第二个乘法操作可以使用MULT18*18来实现;如果它的位数很少、计算规模很小的话,也可以考虑使用CLB来实现。也可以加入流水线操作来提高整个大乘法的性能,因为这样可以充分利用专用乘法器的运算能力。如果这个大乘法的两个输入都超过18位,那就需要把它分解为4个小乘法,但是很容易将最后的几个LSB位上的纯粹的无符号的结果与MSB上的36位的有符号的乘积结合起来,并于其余的两个小乘法的结果相加。
图2提到的是在乘法器介绍的第一篇博文中已经提到的35*35位的有符号乘法操作,它就是通过把4个专用的硬件乘法器和两个加法器级联之后得到的。其中固定位数的加法器是53位宽度的,因为一个输入的17位LSB总是0。另一个34位*34位的无符号子模块,可以使用同样简单的方式得到。

图2 35*35有符号乘法器
2. 使用一个原语执行两个乘法操作
Spartan系列的专用乘法器是18*18位,那如果输入的两个操作数都只有几位时,剩余的位数是不是被浪费?幸好Spartan的专用乘法器具有使用同一个专用硬件乘法器同时处理两个乘法的能力。通过把一个值放在LSB中,另一个放在MSB中,就可以得到两个独立的输出了,只要保证它们的运算结果不会互相覆盖就可以了。把某一位向MSB移动n位,就相当于乘了2的n次方。假如被移动的数值是x,则移动之后变为x*2^n;如果LSB中是y,则乘法器的输入就变成了x*2^n+y。
为了简化描述的过程,下面以使用同一个乘法器(MULT18*18)来求解两个平方操作来说明。下面的公式解释了这个乘法的详细过程。
首先,我们可以很容易得到
(x*2^n+y)(x*2^n+y)=x^2*2^(2n)+xy*2^(n+1)+y^2 (1)
当y=0时,式(1)变为x^2*2^(2n),此时x^2位于输出的MSB上。
当x=0时,式(1)变为y^2,此时x^2位于输出的LSB。
当x=0且y=0时,式(1)变为0.
当x和y都不等于0时,需要小心分配位数以避免结果中的MSB、LSB和中间的数xy*2^(n+1)互相覆盖。在满足以下的条件时,两个乘法可以在同一个专用乘法器中共存,其中x、y均不为0;
[x^2*2^(2n)]min> [xy*2^(n+1)]max
[xy*2^(n+1)]min>(y^2)max。
表1给出了满足这个不等式组的x和y的组合情况。

表1 满足条件的x和y的值
图3给出了在使用同一个乘法器(MULT18*18)来实现两个平方同时计算时的链接关系图,其中一个是6位的有符号数,另一个是5位的无符号数。

图3 一个专用乘法器实现两个乘法
时间不早了只能先写到这儿了。最后补充一个在XST、Synplify、LenardoSpectrum中使用Verilog来描述同步硬件专用乘法器的代码。祝大家周末愉快!
//The following is a Synchronous Multiplier Verilog Example coded for Synplify //and XST:
module mult18x18s(a,b,clk,prod);
input [7:0] a;
input [7:0] b;
input clk;
output [15:0] prod;
reg [15:0] prod;
always @(posedge clk) prod <= a*b;
endmodule
//The following is a Synchronous Multiplier Verilog Example coded for //LeonardoSpectrum:
module mult18x18s (a,b,clk,prod);
input [7:0] a;
input [7:0] b;
input clk;
output [15:0] prod;
reg [15:0] reg_prod, prod;
always @(posedge clk) begin
reg_prod <= a*b;
prod <= reg_prod;
endmodule

附件大小Biao_1_Man_Zu_Tiao_Jian_De_xHe_y.jpg49.08 KBTu_1_2216Wei_Cheng_Fa_Qi_De_Shi_Xian_.JPG16.27 KBTu_2_3535You_Fu_Hao_Cheng_Fa_Qi_.jpg33.31 KBTu_3_Ge_Zhuan_Yong_Cheng_Fa_Qi_Shi_Xian_Liang_Ge_Cheng_Fa_.jpg21.71 KB
记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表