FPGA高效乘法器,性能卓越,轻松应对计算挑战,值得一读。

2024-03-08

01 设计思路   二进制的乘法运算与十进制的乘法运算相似,如下图所示,二进制数据6’b110010乘以二进制数据4’b1011,得到乘积结果10’b1000100110。FPGA高效乘法器,性能卓越,轻松应对计算挑战,值得一读。 (https://ic.work/) 可编辑器件 第1张
FPGA高效乘法器,性能卓越,轻松应对计算挑战,值得一读。 (https://ic.work/) 可编辑器件 第2张
图1 二进制乘法运算 仔细观察上图发现,乘数最低位为1(上图紫色数据位),则得到紫色数据,乘数第1位为1,将被乘数左移1位,得到橙色数据,然后乘数的第2位是0,0乘以被乘数为0,则舍弃。乘数的第3位为1,则将被乘数左移3位,得到红色数据。然后将紫色、橙色、红色数据相加,得到乘积。 这就是二进制乘法运算思路,乘法的运算时间与乘数的位宽有关。乘数为1时需要左移的位数与数据位的权重其实有关,但是FPGA实现这样的运算并不算特别简单,还能不能简化? 当乘数或者被乘数为0时,直接输出0即可,不需要运算。 当乘数和被乘数均不等于0时,乘积的初始值为0,每个时钟周期把乘数右移一位,被乘数左移一位,如果乘数最低位为1,则乘积等于乘积加上此时被乘数的值,当乘数为1时,计算完成,输出乘积的运算结果。 计算流程如下图所示,其实就是将图1的运算拆分,每次只需要判断乘数的最低位是否为1,从而确定乘积是否需要加上被乘数,乘数每右移一次,被乘数就必须左移一次,这样能保证乘积不变。当乘数变为1时,移位结束,此时乘数最低位为1,被乘数加上乘积后作为运算结果,完成运算。FPGA高效乘法器,性能卓越,轻松应对计算挑战,值得一读。 (https://ic.work/) 可编辑器件 第3张
FPGA高效乘法器,性能卓越,轻松应对计算挑战,值得一读。 (https://ic.work/) 可编辑器件 第4张
图2 简化的移位相加运算,02 代码设计   由此,就可以编写FPGA代码了,为了模块通用,位宽全部进行参数化设计,增加开始计算信号和模块忙闲指示信号,以及乘积计算完成的有效指示信号。 端口信号如下表所示>
表1 端口信号列表
 
当开始计算信号有效且乘数与被乘数均不等于0且模块不处于运算状态时,把开始计算信号start_f拉高,运算状态标志信号flag初始值为0,当检测到开始运算start_f有效时拉高,当乘数为1时结束运算,flag信号拉低,对应代码如下所示>
 
 
 
 
然后就是对乘数和被乘数信号的处理,如下所示。初始值均为0,当开始运算时,将输入的乘数和被乘数保存到相应寄存器中,如果flag信号有效,则每个时钟周期把乘数右移1位,把被乘数左移1位。
 
 
 
 
之后就是乘积的运算,初始值为0,当开始信号有效时,不管乘数和被乘数的状态是什么,将乘积寄存器设置为0。在之后的运算中,如果flag有效并且乘数最低位为1,则把乘积寄存器的值与被乘数寄存器的值相加,得到乘积寄存器数据。
 
 
 
 
最后就是乘积运算的输出,如果开始信号有效时,乘数和被乘数其中一个为0,则乘积输出0,拉高乘积有效指示信号。如果在计算乘积的过程中(flag为高电平)且乘数等于1,则表示计算完成,把乘积寄存器值加上此时被乘数的值作为乘积输出,并且把乘积有效指示信号拉高一个时钟周期。乘积有效指示信号在其余时间均为0。
 
 
 
 
最后就是模块忙闲指示信号,当开始信号有效或者模块处于计算状态时拉低,其余时间拉高,上游模块检测到该信号后就可以拉高start信号,开始下一次运算。注意该信号只能使用组合逻辑电路生成,并且上游只能通过时序电路检测该信号状态。
 
 
 
 
代码就这么多,相对比较简单,参考代码如下>
 
 
 
 
03 模块仿真
对应的TestBench如下所示>
 
 
 
 
FPGA高效乘法器,性能卓越,轻松应对计算挑战,值得一读。 (https://ic.work/) 可编辑器件 第5张
图3 仿真截图 至此,该模块的设计到此结束,该模块的位宽全部进行了参数化处理,需要修改乘数和被乘数的位宽时,只需要修改位宽的参数即可,代码不需要做任何修改。 该模块在后续设计中可能作为子模块出现,因为这种靠移位和加法的运算,在面对较大位宽的乘法运算时,可以得到更高的时钟频率。

文章推荐

相关推荐