首先声明一下本人在FPGA这条道路上走了还不到一个星期,对于很多FPGA硬件软件方面的知识理解还很不到位,所以下文必然会有很多漏洞,还希望大家多多指正,共同学习。
本文所用代码基于特权乘法器设计实验一节,代码见下面链接:http://group.ednchina.com/1375/21236.aspx
在看特权大哥16位乘法器视频的时候,一直没有弄明白最关键的乘法操作的两句话,红色标记如下:
else if(i > 5'd0 && i < 5'd16)
begin
if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]}; //累加并移位
else yout_r <= yout_r>>1; //移位不累加
end
else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg; //累加不移位
刚开始是对乘法以为的原理不太懂,后来在草稿纸上退到之后基本明白了,先以两个4位二进制数为例,将推导思路解释一下:
根据这个竖式,可以总结出这样一个规律:
用4位二进制乘数的最高位乘以被乘数时,得出的结果最高只可能出现在第7位上(从广义上说就是结果的次高位上),所以第八位(广义上说就是最高位)只是用来准备存放进位的。
如果读者能够明白这样一个规律的话,那么我们接着就以特权的代码进行分析:
首先要搞清楚在代码{1'b0,yout[30:15]+breg,yout_r[14:1]}中[14:1]和[30:15]指的是原来数的这些位 而它们对应的 现在这个数的位数又分别是[13:0]和[29:14],所以这里其实就实现了右移操作。
对于第31位刚开始始终不用,每次都把结果存放在第[29:14]位之中,15个右移后,最终将真正个位数移到了最低位(0位)。
这里有个问题需要说明一下:
细心的读者估计已经发现{1'b0,yout[30:15]+breg,yout_r[14:1]}这条语句中位数怎么算都是31位啊,明明应该是32位的嘛(视频里也说是32位的啊)为什么会出现这个bug呢?
这里,有些网友是这样解释的yout[30:15]+breg 这两个16位数相加如果足够大,肯定是会产生进位的,所以就成了17位。呵呵,现在刚好17+14+1=32位了吧。
但是这个解释有一个很明显的bug:那要是没有进位呢?不还是16位的吗?
笔者认真考虑了一个晚上想了很多解释最终觉得以下两个解释,虽然自己也不是很有信心,但勉强可以支撑一下这个算法:
1,对于verilog语言“+”会产生一个一个加法器,而加法器都是会带进位位的,所以yout[30:15]+breg会自动产生一个进位位,变成17位。
2,即使上面一个说法不成立,那么当{...}中不足32位时应该会在最高位自动补0或者X吧,这样最终依然是32位。并且不影响后面的计算结果。
对于这样两种猜想,由于本人能力有限,且刚刚接触FPGA所以不敢保证不是谬论,还希望高手们要多多指教。
上面啰嗦了这么多,其实只是对特权大哥代码的一个解读,真正有问题的是下一句:
根据上面总结出的那个规律,最高位只是用来进位用的那么这句代码:
yout_r[31:16] <= yout_r[31:16]+breg;
就明显有问题了,如果两个加数相加产生进位该怎么办呢?
所以我认为这一句应该是需要这么写的:
else if(i == 5'd16 && areg[15]) yout_r[31:15] <= yout_r[30:15]+breg;
呵呵,在我写此文的时候,发现特权的博客上已经有前辈这么提出来了,果然论坛上还是有高手的,这里只是思路相同,没有抄袭之想法还请高手看到此文章后别误会。
下面是通过Modelsim仿真出来的结果:
(图一,为特权代码的仿真结果)
(图二,为修改后代码的仿真结果)
(图三为正确答案)
后记:
在笔者写这篇文章的时候同时还看到了有人这样修改了代码:
else if(i > 5'd0 && i < 5'd16) begin
if(areg[i-1]) yout_r = {1'b0,yout[31:15]+{1'b0,breg},yout_r[14:1]};
else yout_r <= yout_r>>1;
end
else
if(i == 5'd16 && areg[15]) yout_r[31:15] <= yout_r[31:15]+{1'b0,breg};
应该说思路是一样的,这位网友强制加了一位作为进位位,纠正了进位位的丢失。对于这个代码我也随即抽了几个数做了一下仿真,结果完全正确。
结果如下:
最后
特别鸣谢:特权大哥还有论坛上的那些提供意见和代码的高手们。
用户1838426 2015-5-22 09:33
用户1838426 2015-5-22 09:21
用户1838426 2015-5-22 09:09
用户377235 2013-7-24 11:00
用户377235 2013-7-24 11:00
你好,请问乘法中不是左移么,为什么我看都是右移呢,而且为什么移动的是作为输出的y?还有breg为什么加在14——29位上?望各位给菜鸟级的我回答一下
用户1408266 2012-10-7 22:07
用户295512 2012-4-9 12:58
用户1647523 2012-2-17 16:59
用户380725 2011-9-25 10:55
用户1696769 2011-9-23 16:39