FPGA进阶(四)如何在书写代码时进行面积优化

如何在书写代码时进行面积优化

在之前讨论进行速度优化时候已经了解到,速度和面积往往是一对矛盾体,在此我们来讨论以下在写代码时候如何进行面积优化。

一、操作符平衡

之前介绍过通过使用括号来对乘法操作符进行平衡,使得各个输入到输出的延时从三级乘法减少到了两级乘法,从而达到速度优化的目的。同样,操作符平衡还可以达到面积优化的目的。可见操作符平衡是一个一举两得的好方法。通过下面这个例子可以看出是如何减小设计面积的:

如上图的例子,其代码是result <=abc*d;下图给出了其综合布局布线之后逻辑资源消耗情况:

从上图可看出此电路共消耗了89个ALUT。
在进行操作符平衡之后,可以得到如下电路:

其资源消耗如下图所示:

可以看出此电路的ALUT减小到了36,而消耗了一个9位的乘法器。可见通过适当的操作符平衡可以使得片上的资源得到合理的利用。

二、打破设计流水

在之前的速度优化提到了插入流水线的方式,相反,通过去除一些流水线可以达到优化面积的效果。创建流水的时候,需要更多的资源来保存中间值或者需要复制一些需要并行运行的运算结构,所以需要消耗更多的面积。当需要优化面积的时候,需要进行相反的操作,即打破或消除流水,让逻辑得到重复利用。
首先看下图所示的综合出来的电路:

此电路消耗的逻辑资源如下图所示:

此图表明消耗了16个寄存器,1个乘法器,从此处资源消耗可以看出,第一级流水会消耗16个寄存器,剩下的寄存器全部被合并到了DSP乘法器中了,并不占用FPGA的逻辑资源。
现在撤除一级流水,先说撤除第二级流水的情况,撤除第二级流水使得两级乘法器合并在了一个时钟周期下,其综合出来的电路逻辑图如下:

此时第两级乘法器左右的寄存器依旧综合在了一个DSP乘法器下,其所消耗的逻辑资源是没有变的,但是其最大时钟频率因为两个乘法器的合并而变小。
撤除第一级流水之后,即输入信号不经过寄存直接输入到乘法器中,可以得出此时也不需要16个乘法器对输入进行寄存了,所以直接会减少16个寄存器,其他逻辑资源消耗不变,其逻辑资源消耗如下图所示,并且最大时钟频率得到不小的提升。

现撤除第三级流水,即最后一个乘法器的输出不去寄存,此时得到的逻辑资源消耗情况如下图示:

可以看出,此时寄存器多消耗了16个,这是因为此时的结果未使用DSP中的寄存器寄存,因此撤出第三级流水是没必要的,可以的话,尽量使用DSP中的寄存器进行寄存。其实这样可以使乘法 器的输人输出路径更紧凑,利于优化设计速度,同时又不会带来额外寄存器资源的消耗。
**Tips:**为何撤除流水性能反而会有些许提升呢?这是因为数据路径到乘法器的 路径并未进行很好的规划,每次都是通过编译器随机编译,同时这个设计相对简单,无法真实反映复杂设计数据路径的走线状况,

三、资源共享

首先要说明,这里所提的资源共享,不是指底层布局布线工具中的优化选项而是指处于更髙层级或更抽象层级的结构化资源共享,这种抽象代码级的资源共享是指资源通过跨不同功能模块边界的共享,也即某个功能模块可以在一个设计中多个地方使用或者同一个模块可以在不同设计中使用。
概括来说,资源共享一般分为两种,第一种是可以在互斥功能函数中共享操作运算符;第二种则是可以在不同地方同时使用的子模块或子表达式。
在互斥操作中共享操作符
比如加法器的输出Q是A加上C或者B,A与C、B 哪个相加由选择信号S决定,所以需要在设计中采用多路选择器,在结构上可以得到两种方式。两种方式分别如下图所示:

显然,第二种设计占用资源要小一些。
共享表达式
通常,逻辑电路需要多次使用到某个表达式,这时如果通过一个临时变量来保存这个表达式,那么该表达式可以在电路中多次复用,而复用的时候并不需要重复计算表达式,只需要使用临时变量中的数值即可。
例如:
y<=abc;
z<=bcd;
综合出来的电路如下:

y<=a*(bc);
z<=(b
c)d;
综合出来的电路如下:

可以看出,合理的使用括号可以使得表达式“b
c”被后面两个乘法所共享,理论上总共只需要3个乘法器即可。
通过这个例子可以看出共享乘法器(合理使用括号),不但可以优化速度,同时还可以优化面积。
共享逻辑功能块
很多设计都会使用多个计数器,这些计数器分别用于计时、时序控制以及状态机控制等。大部分时候,这些计数器都可以被安排在设计层次的更髙层级,这样就可以被分配给低层级的多个功能模块使用。
例如:设计中A和B两个模块由于不同的原因都需要使用计数器。 模块A使用计数器每256个时钟周期产生一个标志信号。模块B使用一个计数器产生一个频率固定为50kHz、占空比可调的脉宽调制脉冲(PWMX如果时钟还是100MHz,那相当于需要2000个系统时钟周期产生一个脉冲)。
其模块原理图如下:

每个模块都完成各自独立的功能,每个模块中的计数器也都有完全不一样的特性。在模块A中,计数器为8位,自由运行且溢出时自动清零循环。在模块B中,计数器为11位,计数到预设值1999时清零循环。
但是这些计数器还是可以非常容易地融合到一个全局的计数器中,并被模块A 和B共同使用,通过创建一个全局11位计数器同时满足了模块A 和B的需求。
这里需要注意的是,计数器模块为PWM预设计满清零的值为2047而非1999,。这是因为1999和2047相差不大,不会使PWM脉冲受到太大影响,其次是这样清零不会影响模块A的功能;否则,模块A很可能会漏掉一次脉冲输出。
这样可以共享计数器,达到优化面积的目的。

四、复位信号的选择

在一个设计中,如果不需要加复位信号,则不添加复位信号,若需要加,则最好选择异步复位信号,因为根据逻辑器件本身寄存器自身结构,可知寄存器的异步复位不需要消耗额外的资源。

五、从器件角度节省资源

利用厂家原语进行面积优化
例如Xilinx有一个SRL原语,可以很方便地实现移位寄存器的功能。使用此语言比使用verilog语言更加节省资源。
巧用触发器的控制端口
触发器本身除了数据输入输出和时钟端口外,还包含其他各种端口,比如清零、置位、加载以及时钟使能等。这里通过一些小例子来展示如何使用复位和置位端口来实现其他的一些逻辑功能,而不用消耗额外的资源。
1、如下图所示,左侧的或门逻辑功能在右侧的电路中由触发器的置位端口来实现。

2、如下图所示,左侧的与门逻辑功能在右侧的电路中由触发器的清零端口来实现。

前面讨论到“慎用复位”也有这方面的原因,所以才会说片内资源的置位与复位端口被消耗可能会阻碍某些组合逻辑的优化(这种优化一般都是综合工具自动完成的)。
同时要注意,如果不按优先级顺序书写代码,则需要消耗额外的资源。下表列出了寄存器控制端口的优先级:

总结:面积优化方法有5:
一、操作符平衡
二、打破设计流水
三、资源共享
四、复位信号的选择
五、从器件角度节省资源

注:本文参考了FPGA设计实战演练(高级技巧篇)作者:王敏志

  • 9
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FPGA(Field-Programmable Gate Array,现场可编程门阵列)是一种集成电路芯片,可以通过配置电路连接来实现不同的功能。在FPGA进阶之路的第二部分,我们将讨论几个重要的主题。 首先,我们将研究FPGA的架构设计。了解FPGA架构可以帮助我们更好地理解FPGA的内部结构和功能,从而优化设计。我们将学习FPGA中的逻辑单元、存储单元和I/O资源等基本组件,以及它们如何相互联系来实现复杂的电路功能。 接下来,我们将进一步研究FPGA序设计。序设计是确保电路在不同钟周期下正常工作的关键。我们将深入了解钟和钟域的概念,以及如何进行序分析和序约束。理解序设计将有助于我们减少电路的序故障,并获得更高的性能和可靠性。 此外,我们还将介绍FPGA的高级综合和硬件描述语言(HDL)。高级综合是一种将高级语言代码转换为FPGA可执行代码的技术,可以帮助我们更快地开发和验证电路设计。常用的HDL语言包括VHDL和Verilog,掌握这些语言可以帮助我们有效地描述和设计FPGA电路。 最后,我们将讨论FPGA的应用领域。随着技术的进步和FPGA的性能提升,它在许多领域都有广泛的应用,包括数字信号处理、网络通信、嵌入式系统和人工智能等。了解这些应用领域可以帮助我们选择适合的设计方法和工具,提高FPGA的实际应用价值。 总结起来,FPGA进阶之路的第二部分主要涵盖了架构设计、序设计、高级综合和HDL以及应用领域等方面。通过深入学习这些内容,我们可以更好地理解和应用FPGA,提高电路设计的效率和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值