这一章来讨论数字设计的第三个基本物理特性,即功耗。当然本章我主要关注在代码阶段通过何种方式来优化FPGA的功耗。
与ASICs(Application Specific Integrated Circuits)比较,相似的逻辑功能,用FPGA来实现需要消耗更多的功耗,而且FPGA通常并不适合超低功耗设计技术。许多FPGA的供应商提供一种低功耗逻辑芯片,即CPLD,但是CPLD非常受限于尺寸和能力,因此将无法总是满足那些需要数量可观的功耗的应用。本章将详细讨论低功耗CPLD和通用FPGA设计功率效率最大化技巧。
在CMOS技术中,动态功耗与门电路和金属走线中的寄生电容的充放电有关。一个电容的电流损耗的通用公式如下所示:
I=V*C*f
这里I是总电流,V是电压,C是电容值,而f是指频率。
那么,为了减小电流,那么我必须减小公式右边三个关键参数中的一个即可。在FPAG设计中,电压通常是固定的,所以只留下C和f可以用来改变电流。电容C和给定时间内处于活动的门电路数量以及连接这些门电路的走线长度有直接关系。而频率f则和时钟频率直接相关。所以所有降低功耗的技术都绝对针对于减少这两种参数。本章将主要讨论以下一些可以降低功耗的技术:
l时钟控制对于动态功耗的影响
l使用门控时钟的问题
管理门控时钟上的偏斜
l输入控制以最小化功耗
l核心供电电压对功耗的影响
l触发器双沿触发指导
l终端匹配降低静态功耗
通过减少高翻转率网络的布线长度来降低动态功耗的讨论,需要有了解布局布线的背景,因此这种技术不在本章介绍范围内,将在后面有关Floorplanning的章节进行详细讨论。
3.1 时钟控制
在同步数据电路设计中,降低动态功耗最有效以及使用最广的技术是在某些指定区域数据流的特定阶段不需要时钟处于活动状态的时候禁止时钟活动。因为FPGA的动态功耗大部分时候是与系统时钟的翻转有直接关系,所以临时性地停止设计中某些处于非活动区域的时钟往往是最小化这类功耗最直接的方法。为了达成此目的,有两种推荐方法,一种是在触发器中使用时钟使能,另外一种是使用全局时钟多路选择器(Xilinx器件中称为BUFGMUX单元)。如果这些时钟控制单元在一些特定技术中无法实现,设计者此时往往诉诸于门控系统时钟。需要注意的是,门控时钟在FPGA设计中是不被推荐的,而且这一章我们还会详细讨论直接门控系统时钟将会带来的一些问题。因此,如果有可能尽量使用触发器的时钟使能输入或者全局时钟多路选择器来代替时钟门控。
在进行后续讨论之前,我们假定读者已经非常熟悉FPGA的时钟设计指导。通常,FPGA是同步器件,而且通过门控或者异步接口引入多时钟域往往会增加FPGA设计的难度。有关时钟的更深层次讨论,我们后续在有关时钟域一章中进行详细说明。
图3-1显示了一种包含简单门控时钟的蹩脚设计。使用这种时钟拓扑结构时,所有触发器以及相应的组合逻辑在主时钟活动的任何时候都处于活动状态(即处于翻转中)。然而,处于虚线框中的逻辑只有在时钟使能等于1的时候才处于活动状态。这里所指的时钟使能信号,就是门控或者使能信号。通过像图3-1那样门控部分电路,根据被门控的逻辑量(对应于电容C)以及对应门控的平均频率(对应于频率f),设计者可以尝试成比例地减少动态功耗。时钟门控是降低动态功耗的直接手段,但是会带来设计实现以及时序分析难度的增加。
<ignore_js_op>
图3-1:带简单门控时钟的蹩脚设计
在我们接着往下讨论之前,需要注意的很重要一点是仔细规划时钟在FPGA设计中是非常重要的。系统时钟是所有同步数字电路的核心。EDA工具都由系统时钟驱动来优化和时序综合、布局布线以及静态时序分析等等。所以,要认真对待系统时钟或者其它时钟,并在设计实现整个过程中必须被赋予最大优先级考虑的特性。在FPGA设计中,时钟要比在ASIC设计中更严肃地对待,因此相比ASIC设计相应创建时钟结构的灵活性就更小。
时钟被门控后,这个被门控的新网络所驱动的所有时钟端口都应该至少被认为是一个新的时钟域。同系统时钟一样,这个新的时钟网络到该时钟域的所有触发器都需要一个低偏斜的路径。对于ASIC设计者来说,这些低偏斜时钟走线可能已经内置在用户时钟树中,但是对于FPGA设计者来说这将成为问题,因为FPG**内低偏斜走线资源不但数量有限,而且分布固定。因此,我们说门控时钟在给设计引入新的时钟域同时,还给FPGA设计者增加了设计上的难度。本节后面我们来介绍由门控时钟引入的这些问题。
3.1.1 时钟偏斜
时钟偏斜是时序逻辑设计中一个很重要的概念。在直接谈论门控时钟相关问题之前,我们必须首先有必要简要回顾一下时钟偏斜(skew)的定义。
如图3-2所示,假定第一个触发器和第二个触发器之间的时钟信号传播延迟为零。如果通过“云朵”中的组合逻辑的延时是正的,那么设计时序将会得到符合,时序是否符合将由时钟周期相对于组合逻辑延时加上逻辑布线延时再加上触发器建立时间来确定。每个时钟周期,一个信号只能在一组触发器对之间传输。不过,图3-2中第二个和第三个触发器之间的情况与前一级有所区别。因为时钟走线到第二和第三个触发器的延时不一样,即时钟正沿不是同时到达这两个触发器。如图所示,时钟正沿是经过了一个延时为dC后才到达第三个触发器的。
<ignore_js_op>
图3-2:时钟偏斜
如果通过逻辑的延时(定义为dL)小于时钟线上的延时(dC),那么就会发生一种情况,即从第二个触发器传输到第三个触发器的信号将会早于时钟正沿到达第三个触发器。所以当时钟正沿到达第三级时,相同信号有可能也由该触发器输出。那么,就会造成一个信号在第二级和第三级上在同一个时钟上升沿时被送出。这个情况将导致电路出现灾难性错误,所以时钟偏斜在时序分析的时候必须要考虑到。需要注意的是时钟偏斜与时钟速度并无关系,这一点很重要。所以,上面描述的信号“飞越”两级触发器的问题发生的时候,是完全无视当前时钟的频率。谨记这个观点,处理时钟偏斜不当,将会给FPGA设计带来灾难性的错误。
3.1.2时钟偏斜管理
FPG**内提供一种低偏斜的资源,这种资源可以确保时钟信号到所有时钟端口的延时都尽可能的一致(皮秒级)。举例来说,我们来看这样一种情况,即一个门被引入到了时钟网络,如图3-3所示。
<ignore_js_op>
图3-3:蹩脚设计之时钟门控引入时钟偏斜
这时候时钟线必然要离开低偏斜的全局资源并被布线到逻辑门,这里是一个与门。如此时钟线上增加了偏斜,增加偏斜带来的基本问题和我们上一节描述的一样。可以想象,经过与门的延时(dG)再加上走线延时,那么时钟到最后一级触发器的延时将会大于信号的逻辑延时(dL)。为了解决这个潜在的问题,必须给逻辑实现和时序分析工具施加一系列约束,这样任何与由逻辑门引入的偏斜有关的时序问题将会得到解决,而且实现也能在实现后得到正确地分析。
下面我们来看一个具体的例子,下述代码是一个使用了门控时钟的蹩脚设计。
以下是代码片段:
module clockgating(
output dataout,
input clk,datain,
input clockgate1);
reg ff0,ff1,ff2;
wire clk1;
//当逻辑门为低时时钟被禁止
assign clk1=clk&clockgate1;
assign dataout=ff2;
always @ (posedge clk)
ff0<=datain;
always @ (posedge clk)
ff1<=ff0;
always @ (posedge clk1)
ff2<=ff1;
endmodule
上例中,数据路径上没有任何组合逻辑,但是时钟路径上有组合逻辑,如图3-4所示。
<ignore_js_op>
图3-4:时钟歪斜主导的延时
不同的工具,将会采样不同的方式来处理这种情况。有些工具,比如Synplify,默认会将时钟门控逻辑移除,从而创建一个纯同步设计。而其它一些工具会在时钟缺乏约束的时候忽略掉时钟歪斜问题,但是,一旦时钟被正确约束的时候会人为地在数据上加入延时。
和ASIC设计不同,由于逻辑块和布线资源中内置有延时,所以FPGA设计中发生保持时间违规是非常罕见的。但是,如前所述,如果在时钟线上进行过渡的延时,就有可能导致保持时间违规。比如,我们可能面临这样一个事实,即数据传输延时小于1ns,而时钟延时几乎达到了2ns,这样数据几乎比时钟提前1ns到达,从而导致了一个严重时序违规。根据综合工具的差异,有时,这个问题可以通过添加时钟约束来得到解决。所以,后续的时序分析也许会或者不会(完全依据技术)展现在数据路径上人为地添加的布线延时来消除保持时间违规的问题。因此,因门控时钟导致的保持时间违规可能会被工具解决,也可能不会。
这里值得再次重申的是,大部分供应商都能提供高级时钟缓冲技术。这种技术使得器件可以建立全局时钟树。我们总是建议大家采用这类时钟控制,而不是上述通过逻辑单元实现的时钟门控。
3.2 输入控制
有一种可以降低功耗的技术通常都容易被大家忽略,即可以通过降低输入的上升沿斜率降低功耗。在上下两侧晶体管同时导通的时候,CMOS的输入缓冲会产生持续的吸电流。为了描述方便,我们来看一个CMOS晶体管基本阶模型,如图3-5所示,为Ids-Vds曲线图。
<ignore_js_op>
图3-5:CMOS晶体管简单的I-V曲线
图3-5中,Vgs是栅源电压,Vth是器件门限电压,Vds是漏源电压。各段曲线区域分布被定义为:
截止区:Vgs <vth</v
线性区:0 <vds < Vgs - Vth</v
饱和区:0 < Vgs – Vth < Vds
那么管子在理想情况下的开关动作应该是这样的,N沟道MOS管当输入到栅极时管子从截止区瞬间切换到线性区,而P沟道MOS管应该瞬间执行上述相反的切换动作。不管N沟道还是P沟道MOS管,假如管子一直是处于截止状态,那么管子中就不会有电流(也即电压和地之间阻抗很大)。以一个反相器举例来说,如果由NMOS(N沟道MOSFET)来实现的话,从0跳转到VDD(正电压轨)意味着NMOS从截止区瞬间切换到线性区,而如果是PMOS(N沟道MOSFET)则是从线性区瞬间切换到截止区。相反,如果Vgs从VDD跳变到0,那么NMOS从线性区瞬间切换到截止区,而PMOS是从截止区瞬间切换到线性区。
然而在实际系统中,我们必须要考虑MOS管中晶体管的切换时间以及导通特性。还是以以一个CMOS反相器为例,反相器输入一个0伏,那么输出一个VDD。当输入从0变化到VDD时,一旦输入达到门限电压Vth后NMOS晶体管就会离开截止区,并进入饱和区。对于PMOS来说,在上述变化前期还一直处于线性区,所以在VDD和地之间会有电流。随着输入的增大,输出下降。当NMOS的漏极电压低于栅极电压的门限电压时,NMOS进入线性区,而PMOS进入饱和区随后进入截止区。为了最小化功耗,有必要最大限度减小饱和区的时间,也就是说最大限度减小输入的跳变时间。总结来说,就是最大限度减小输入信号的上升和下降时间可以最大限度地降低器件输入引脚的功耗。
根据前面划分曲线各个分区的公式,我们还可以得出另外一个重要的结论。即如果驱动信号在没有开关切换的时候未处于稳定状态,比如超出0或者Vdd规定的限值范围,那么晶体管就将会从之前的截止区进入饱和区,并且开始消耗小部分的电流。这在小摆幅信号驱动高电压供电的输入时,将会给系统带来问题。
和上面描述的原则类似,在FPGA设计中,一个悬空的输入引脚要比一个有驱动的输入引脚更糟糕。FPGA的引脚悬空,一般都被认为带驱动的输入,但是由于其悬空,所以无法得知它到底是如何被驱动的。那样悬空有可能被认作亚稳态,那样两种晶体管都将会处于饱和区。如此将会给功耗带来灾难性的影响。同样糟糕的是,这是个无法复现的问题。因为大部分FPGA器件都能提供阻抗匹配,所以一个好的设计应该将那些未用到的输入引脚定义一个可知的状态,这样可以避免由于引脚悬空带来的不可预知的影响。
3.3 降低供电电压
虽然降低器件的供电电压通常不是一个值得尝试的选项,但是这里还是有必要提一下其对于功耗的戏剧性影响。我们知道,一个简单电阻上功耗即功率与加载其上的电压的平方成正比。那么,通过将FPGA的供电电压降低到电压要求的最低值,可以显著地降低FPGA的功耗。然而,需要特别注意的是,降低供电电压也会降低系统的性能。如果需要采取这种方式来降低功耗,那么就需要确保时序分析最快时序时已经考虑到在供电电压处于最低要求时这种最坏的情况。所以,我们可以得出这样的结论,FPGA的动态功耗会随着核心电压的平方成比例降低,但是降低电压对于FPGA的性能会造成负面的影响。
因为一般FPGA都规定电压的正常工作范围为工作值的5%到10%,所以千万要注意从系统设计方面综合考虑。通常来说,为了很好地保持核心电压在一个指定的范围内,电源问题可以通过其它技术解决。
3.4 触发器双沿触发
由于事实上功耗部分地和信号翻转频率相关,所以对于那些高扇出网络,最好尽可能地扩展其每次翻转的功能。大部分时候,一个系统的最大扇出网络通常是系统时钟,那么任何降低该时钟频率的技术都会对动态功耗产生戏剧性影响。所谓的双沿触发触发器,是提供了一种在时钟的上下沿传播数据的机制,而不只是单单使用时钟的单个沿。如此就使得设计者可以在时钟速度减半的情况下获得之前全速时钟下一样的功能和性能。
在代码中可以非常直接地设计双沿触发的触发器,下面这个代码示例就通过一个简单的移位寄存器对此进行了展示。注意这个例子中的输入信号在时钟的上升沿被采集,接着被送入双沿触发器。
以下是代码片段:
module dualedge(
output reg dataout,
input clk,datain);
reg ff0,ff1;
always @ (posedge clk)
ff0<=datain;
always @ (posedge clk or negedge clk) begin
ff1<=ff0;
dataout<=ff1;
end
endmodule
需要注意的是,当器件中没有双沿触发器资源时,将会由一些冗长的触发器以及门控逻辑来模拟上述对应的功能。这将完全违反了我们采取双沿策略的最初意图,而且功能实现以后应当得到妥善地分析。对于一个好的综合工具,在发现器件没有双沿触发器的情况,应当至少会给出一个警告信息。所以这种双沿触发器来降低功耗的策略,应该只适用于那些能提供这种资源的器件。
Xilinx的Coolrunner-II家族中的器件就包含有一种名为CoolClock的特性,这种特性可以将输入时钟进行二分频后让触发器工作于上述讨论的双沿状态。从器件外部看来,器件仍然无异于工作在单沿触发的系统,区别在于全局时钟线上的动态功耗减少了一半。
3.5 修改阻抗匹配
带总线信号、开漏或者传输线输出的系统,其输出引脚上通常都连接电阻负载,需要进行终端匹配。上述所有这些例子中,FPGA输出驱动中的一个CMOS晶体管需要通过其中一个电阻负载源出或者吸入电流。因为输出都需要上拉电阻,可以通过最小可接受的上升时间计算出最大可能的电阻。如果总线上同时存在主从驱动器,那么要确保总线竞争的情况不好发生,因为一旦发生,即使只有几纳秒的时间,也会产生过大的电流。对于传输线来说,通常需要在负载处需要分流端接,根据系统的要求也可以使用串行端接替代。如图3-6所示,使用串行端接时,没有稳定的电流耗散。
<ignore_js_op>
图3-6:端接类型
使用串行端接的不利在于:
l从负载到端接电阻有一个初始信号反射
l串联电阻在信号传输的时候会造成一部分衰减
如果一个系统可以接受上述这些不利的性能特性,那么串联端接方案可以通过端接电阻来减少静态功耗。
3.5 优化要点总结
l如果有可能尽量使用触发器的时钟使能输入或者全局时钟多路选择器来代替时钟门控。
l时钟门控是降低动态功耗的直接手段,但是会增加设计实现以及时序分析的难度。
l时钟歪斜处理不当将会给FPGA设计造成灾难性的错误。
l时钟门控会导致保持时间违规,实现工具可能会也可能不会纠正。
l为了最大限度减少器件输入带来的功耗,可以最大限度减小驱动输入信号的上升和下降时间。
l对于未使用到的输入缓冲总是进行端接处理,不要让FPGA的输入缓冲处于悬空状态。
l动态功耗会随着核心电压的平方成比例变化,但是通过降低电压达到减少功耗的同时,会给设计性能带来负面的影响。
l双沿触发的触发器只有在器件可以提供这类资源的时候才应该被使用。
l在串联端接上没有稳定的电流耗散。