开启辅助访问
 找回密码
 立即注册

FPGA高速设计(四)

zj1244 回答数20 浏览数1879
前几章费了好大的功夫才说完了加法器/减法器,后面会稍微加快点速度,今天主要说一下比较器。
三、比较器在FPGA中的实现
比较器可以分为等于/不等于、大于/大于等于、小于/小于等于,从资源和逻辑层级来说,大于、大于等于、小于以及小于等于所使用资源完全一致,所以我们就选取大于比较器进行讲解,同时等于和不等于使用资源一致,我只用等于比较器进行分析。
3.1  等于/不等于比较器
为了分析等于比较器,我们按照4bit位宽为例,用门级电路表示出4bit等于/不等于比较器的结构,其实很简单,就是每位都进行“同或”操作,最终把对比后的结果“相与”,下图所画电路只为等于比较电路,如果是不等于比较器,只需要输出加反向即可。
我们从前面章节了解到,FPGA中的LUT可以实现任何函数运算,那么对于K7芯片,LUT为6输入,所以每个LUT最大可以完成3bit数据的相等/不等比较。

综合电路示意图如下,在vivado中可使用一台LUT6和一台LUT3完成。

由此可以推算出,这种综合方式只使用LUT,并且基本和输入位宽成正比,位宽越大使用的LUT数越多。通过vivado实验,当输入信号位宽大于8后,综合后的电路会改变,和累加器类似,电路会带有CARRY4进位链。这个进位链完成最后一级LUT的功能,由于CARRY4的延迟小于LUT,目的是为了尽量减少延迟,所以是划算的。
下图展示了LUT综合方式和进位链CARRY综合方式不同点。输入信号A和B,位宽均9bit,左边为只用LUT的综合方式,右边为进位链综合方式。对于下图左边,每个LUT6都进行了3位数据的对比,所以9位比较器使用三个LUT6,最后还需要一台LUT3作为与门,将这些中间结果相与,输出最终比较结果。

如果使用进位链,注意:此时LUT6的输出表示不等于。而进位链的选择器逻辑为CO[i+1]=S? DI: CYINT,当S[0]=0时表示低三位都相等,所以输出CO[0]=CYINT=1;当S[0]=1时表示低三位至少有一位不相等,此时CO[0]=DI[0]=0。同理,S[1]=0时表示中间三位都相等,CO[1]=CO[0],意味着低三位相等则CO[1]=1,反之为0;S[1]=1时表示中间三位至少有一位不相等,CO[1]=DI[1]=0。依次类推,最高位也如此。

对于更高位宽比较器而言,前面的LUT逻辑基本都一致,而后级的CARRY4进行了级联,下图表示了13bit相等比较器电路图,原理不多赘述。

总结一下,对于一般相等/不相等比较器,12bit以下都是两级逻辑,位宽极小的使用纯LUT的综合方式,12bit以上,每增加12bit多一级CARRY,参考表格如下。

3.2  大于/大于等于/小于/小于等于比较器
本文只选取’大于’比较器介绍,其余都是类似,占用资源也完全一样。对于单bit的大于比较器,如果用门级电路搭建,则为下图所示,这个电路同时可以输出单比特大于和等于比较,将这个电路作为黑盒,只预留输入输出,当然这个黑盒也可以通过改变输出A>B和A!=B,原理都差不多,后面我们要频繁使用。

如果是2比特的大于比较器,需要将每一比特都进行对比,下图分别为2比特和3比特的大于比较器,分别使用一台LUT4和LUT6。对于2比特输入,先对A[1]和B[1]进行比较,如果A[1]>B[1],或门的其中一台输入为1,那么最终输出也将为1;反之如果A[1]<B[1],或门两个输入都是0,则输出也为0;最后如果A[1]=B[1],表示最高位相等,与门的输出决定了最终的输出,如果A[0]>B[0],与门输出为1,最终输出为1,反之最终输出为0。对于3比特比较器,只是多级联了一级逻辑,原理都是一样的,但是对于FPGA的LUT,是查找表类型,只要输入在规定范围,再复杂的门级电路都只需要一台LUT,所以对于K7芯片来说,4比特以下的大于比较器都只需要一台LUT,大家在评估其他FPGA芯片时,也是需要按照LUT的输入端数量进行计算的,原理都是通用的。

突然觉得用这种LUT综合方式很容易啊,只需要并联LUT就可以解决问题,比如一台6bit的大于比较器,我可以按照下图方式综合,大家可以思考一下是不是正确?

<hr/>给一定空间进行考虑,倒计时——10、9、8、7、6、5、4、3、2、1——”错误!“,开始很容易走进这个误区,上图的电路可以表示相邻3bit是否大于,但是如果出现高3bit相等的状态,是没办法算出正确值的,大家想想是不是这样?
那么正确的答案应该是指什么呢?对了,老老实实级联吧。计算低3bit是否大于,然后对比[3]和[4]位,如果A[4:3]>B[4:3],则LUT5直接输出1。由于K7中LUT最大输入为6,不够了所以要级联LUT,对比A[5]和B[5]……好吧这只是为了省事画综合图的理解,正确的流程应该是反着来的,先对比高位,如果A[5]>B[5],接下来都不用再对比了,直接输出答案就完事了。

这样的综合方式如何?乍一看或是逻辑层级挺高的,如何优化呢?好的方法就是用资源换速度,增加LUT使用,降低逻辑层级,来一起看vivado咋搞的——CARRY综合方式。
vivado好像很喜欢使用CARRY进位链,稍微不用就不舒服,那也没办法,Xilinx的综合方案就是这样搞的,到底哪种综合方式更好想必Xilinx肯定做过评估了毋庸置疑,所以这里我们有必要深入了解一下这种CARRY综合方式,才能在设计代码时知道比较器真正占用资源和逻辑层级。
更大位宽的大于比较器将会使用更多逻辑资源,路径也会更长,和上述的累加器、等于比较器类似,在位宽更大时,vivado选择了延迟更小的CARRY4来替代LUT逻辑,要明白带进位链的比较电路,需要从最简单的1bit说起。如下图所示,这次的”黑盒子“可以输出A>B或者A!=B,CARRY4进位链则作为选择器使用。当S[0]=1,即A[0]!=B[0]时,CO[0]=DI[0],如果A[0]>B[0],则CO[0]=1,反之CO[0]=0;当S[0]=0时,即A=B,此时直接输出CI的值为0,CO[0]=0。如果你只看1bit的大于比较器综合方式,一定会认为Xilinx是不是用1+10-10+1=2去证明了1+1=2?是有点莫名其妙,那我们接着往下看。

为了更省事了解,我再列出2bit位宽比较器综合图,其实和1bit原理一样,也没有觉得有任何省事的地方,因为使用更多的资源实现了相同的功能,会想到刚才展示的LUT综合方式,只用1个LUT就能搞定了,不急不急,再看看。

由上面可以看到对于小位宽的大于比较器,使用延迟链根本没有必要,反而增加了逻辑层级,但是当输入位宽增加后,差距就出来了。比如下图中位宽为8bit的比较器,如果只使用LUT,则需要不断的级联,我们估计一下,如果使用LUT综合方式,是不是需要1个LUT6、2个LUT5以及1个LUT3的级联?那逻辑层级就是4级了,大家可以自行思考一下,这里就不贴图了。
如果按照vivado提供的CARRY综合方式,它会如何搞呢?其实可以将每个LUT作为4输入,先计算出每两位的大小比较,将结果输出,送入CARRY4中,而进位链的好处是有级联的比较器,先考虑最低位[1:0],当S[0]=0,即A[1:0]=B[1:0]时,CO[0]=0;当S[0]=1,即A[1:0]!=B[1:0]时,CO[0]的值取决于A[1:0]是否大于B[1:0]。对于次低位[3:2],当S[1]=1时表示此时A[3:2]!=B[3:2],完全取决的于DI[1],即A[3:2]是否大于B[3:2],不赘述;反而当S[1]=0时表示此时A[3:2]=B[3:2],则需要看低位对比如何,这时需要借鉴低位结果,这个结果就是传过来的地位进位值CO[0],当CO[0]=1表示A[1:0]>B[1:0],从而A[3:0]>B[3:0],反之A[3:0]<=B[3:0]。对于高位比较也如此,不赘述。

通过上述描述可以看出,CARRY4进位链中的多级选择器可以很好的实现逐级对比功能,这在大位宽中非常有用,极大的优化了逻辑层级的猛增,所以位宽大的时候vivado基本都是使用这种综合方式没有任何毛病。但是有一点值得我们去讨论:
vivado为啥不用LUT6进行3bit大小对比,然后再进行CARRY级联呢?这样完全可以节省大量LUT资源。但是遗憾的是,无论我如何努力,把综合策略如何更改,也无法修改它的综合方式,我认为这也许是Xilinx的失误。
既然CARRY综合方式比LUT方式层级少了那么多,那为啥我们还要花篇幅去说LUT综合方式呢?我觉得不管工具用什么样的综合方式,最关键的是我们自个可以去独立分析,当我们考虑多种可能性以后,就不会总停留在一台层次,觉得工具那么高不可攀,它也是人意志的体现,我们也有可能想出比工具更好的方式。
PS:附带一张vivado的综合图,是12bit大于比较器的结果,依然使用了LUT4,让强迫症患者看着几乎奔溃,为啥不用LUT6???。

最后,老规矩,为了省事大家设计,无脑贴出大于比较器的逻辑层级表,同时适用于其他几种类似的比较器,仅作参考,再说一遍不同架构FPGA综合结果不同。
使用道具 举报
| 来自云南 用Deepseek满血版问问看
kwang4 | 来自北京
但是遗憾的是,无论我怎么努力,把综合策略怎么更改,也无法修改它的综合方式

这里会不会是使用的vivado版本问题?有可能新版本的会修复它?
[捂脸]或者尝试给xilinx写个邮件不知道有没有用。
用Deepseek满血版问问看
回复
使用道具 举报
asaqiq | 来自北京
另外综合策略问题(也包括后面的MAP,Place,Route选项)是否在这个专栏将来可能要讨论的主题范围之内?

个人感觉应该是相关的,选不同的策略,确实会带来一定的面积/时序上的变化
回复
使用道具 举报
小皮特 | 来自北京
xilinx还是会修bug的,之前用vivado2018.3,弄了一个AXI Smart Interconnect,结果占用资源异乎寻常地多。
一查才发现,xilinx自己承认这是bug,对这个版本的vivado就是换别的代替,2019.1版本开始修复了这个bug(release note里面也写了)[捂脸]
回复
使用道具 举报
ilovit | 来自北京
厉害了 每天等着楼主更新 做了好几年设计还是对一些底层不够熟悉 谢谢楼主了
回复
使用道具 举报
ending | 未知
想问下楼主,如果对于大位宽的数据,比如256位的,也会逐位进行比较嘛?还是说会考虑减法运算?然后就是方便将原码贴出来吗(比如这这篇文章的)
回复
使用道具 举报
cunddy | 来自北京
大家术业有专攻,互相学习
回复
使用道具 举报
deandy9527 | 来自北京
策略肯定是包括的,平时关注布局布线策略多一些,对综合策略基本没做过研究,通过尝试发现,如果选择减少资源的综合策略,大部分逻辑会进行优化,不过这个“大于比较器”确实综合电路没变过。是应该和xilinx沟通一下,有结果了我后续加上[赞][赞][赞]
回复
使用道具 举报
zjfox | 来自北京
好建议非常感谢,我暂时按照vivado18.2做的分析,后续尝试更换到19.1试试
回复
使用道具 举报
econsky | 来自北京
其实减法逻辑需要的资源和逻辑层级都要高一些,比较的时候没必要使用减法。目前fpga实现比较器都是需要逐级比较的,代码的画因为很基本就没有贴,其实就是always @(posedge clk )
comp <= (A < B);
回复
使用道具 举报

相关问题更多>

123下一页
快速回复
您需要登录后才可以回帖 登录 | 立即注册

当贝投影