但是,估计细心的读者会问,我知道了我所例化的每个存储器的M4K块使用数量,那么我怎么知道是否超出了器件所有的数量,难道非要等到编译出error才行吗?或者自己在这个页面掐指算算再找来handbook比对一下吗?非也,其实用户只要点开FitteràResource SectionàResource Usage Summary,如图6所示,里面罗列了非常详细的FPGA所有片上资源的使用情况,圈出来的部分也是这里我们需要重点关注的地方。M4Ks里指明器件的36个M4K块使用了26个,占用率72%;而Total block memory bits和前面综合报告里是一样的,严格的说,这个数据应该算是片内存储资源的绝对使用情况;最后说Total block memory implementation bits选项,它是最终实现到FPGA器件上的片上资源占用情况(注意这里只能是占用而非使用,汉语文字真是博大精深,也许有些时候两个词怎么用都差不多,但是这里特权同学想区分这个概念,所以刻意要提醒大家注意,因为,它还涉及本文的主题,哈哈,不好意思,有点班门弄斧了),它的占用率和M4Ks是一致的,并且必须是一致的。
图6
那么好,“工欲善其事,必先利其器”,我们利完器,就来说正事。特权同学提出一个概念,就是FPG***上资源的利用率,他的公式为:(Total block memory bits/Total block memory implementation bits),对于该设计就是(62% / 72%) = 86.11%,应该说是个不错的数据(呵呵,悄悄的告诉你,这个实例可是被特权同学优化过了)。
说完这些概念,我们可以真刀真枪的玩一玩了,理论永远只是理论,要提高必须靠实践。其实可以把这个工程打回原形,退回优化前的情况。由于篇幅关系,这里只讨论它优化过程中的一个最显著的例子。
在这个工程中,有一连串的8bit数据流,第1个数据要和第1280个数据做一些处理。因此,最简单的想法就是例化一个1280*8bit的移位寄存器。并且这个移位寄存器在第一个移入的数据移出时,要和此时要正要移入的数据做一些处理。但是,在配置移位寄存器的时候遇到了一些麻烦,如图8所示,移位寄存器的深度一般是用配置的taps数量乘以distance值(建议对移位寄存器配置的相关知识还不熟悉的朋友参考特权同学的另一篇博文《Cyclone M4K移位寄存器使用》)。而这里distance值最大只能配置为256,需要1280个寄存器,并且只用一个taps的想法破灭了,于是思考了下:发现256*5/128*10/64*20都是可行的办法。
图7
刚开始配置的时候没有太多考虑,就选择了64*20的方案,即配置taps = 24(因为taps值只能为可选的1/2/3/4/5/6/7/8/12/16/24/32/48/64/96/128,这里配置为24个taps,而使用的时候取taps输出的bit159-152,实际综合的时候其实会把4个不用的taps优化掉),distance = 64。
如图8所示。如果你够细心,你应该发现了左下角的Resource Usage是6 M4K。
图8
然后就着这样的配置,在编译后可以使用前面提到的方法查看一下存储器资源的使用情况。因为我们重点要算FPG***上资源的利用率,所以还是查看FitteràResource SectionàResource Usage Summary这个报告吧。如图9所示,这个报告中的Total block memory bits和之前没有变,都是62%,而M4Ks占用多了2个,相应的M4Ks占用率和Total block memory implementation bits占用率增加到了78%。计算一下,(62% / 78%) = 79.5%,下降了近7个百分点。也许这个参数说明不了问题,但是在资源紧张的时候,这个问题就是最挠人的问题。