一文详解时钟门控(clock gating)

IoT 8个月前 admin
342 0 0

SOC架构篇

开始之前,我们首先来看一下什么是时钟门控(clock gating)技术,顾名思义就是利用逻辑门技术控制时钟的通断

那么为什么需要控制时钟的通断呢?主要基于以下几个原因。

首先,随着工艺的发展和设计规模的增大,时钟树上产生的功耗占整个SoC功耗的比例越来越高,有时几乎能占到50%左右。

关于时钟树,可能前端的同学不熟悉,简单说几句,SoC的时钟一般是参考时钟经过PLL和数字分频器输出的,后面可能要连接驱动成千上万的寄存器clock端

这时候任何一个单一的cell都不可能有这么大的驱动能力,因此要插入大量的buffer,而且为了保证到每个寄存器的延时一样,clock tree还要做balance。整个的时钟树大概长成下图这样,

  • • 第一级buffer叫root,

  • • 中间的buffer叫branch,

  • • 最后一级的buffer叫leaf(做技术的起名字就是这么简单,粗暴,易懂图片):

一文详解时钟门控(clock gating)
图1 时钟树示意图

如果我们的芯片在不工作时,PLL依然有clock输出的话,那整个时钟树依然产生很大的功耗。

接下来我们再看一下边沿触发器的结构图。从图上我们能看出即使D端保持不动,clock端变化也会消耗一些能量。想深入研究的同学可自行推导(可以忽略两个复位信号)。

一文详解时钟门控(clock gating)
图2 边沿D触发器

那么当D端长时间不变时,是不是可以把CP端的变化隔离掉以降低功耗呢?答案是肯定的。

钟控触发器的特点在于,只有在CP端上出现时钟脉冲时,触发器的状态才能改变。

最简单的办法就是把clock信号和一个EN信号做“与”操作,如下图:

一文详解时钟门控(clock gating)
图3 简单的时钟门控逻辑

这个方法虽然简单,但是如果我们不能保证EN信号相对clock的到来时间和保持时间,那么就很可能不能产生门控时钟或者产生毛刺(glitch)。

当一个逻辑门的输入有两个或两个以上的变量发生改变时,由于这些变量是经过不同路径产生的,使得它们状态改变的时刻有先有后,这种时差引起的现象称为竞争(Race)。竞争的结果将很可能导致冒险(Hazard)发生(例如产生毛刺),造成错误的后果,并影响系统的工作。 

组合逻辑电路的冒险仅在信号状态改变的时刻出现毛刺,这种冒险是过渡性的,它不会使稳态值偏离正常值,但在时序电路中,冒险是本质的,可导致电路的输出值永远偏离正常值或者发生振荡。

避免冒险的最简单的方法是同一时刻只允许单个输入变量发生变化,或者使用寄存器采样的办法。

为了解决这个问题,人们提出了基于锁存器的时钟门控逻辑。由于锁存器能捕捉到EN信号并使它保持到产生完整的时钟脉冲,因此EN信号只需要在时钟活跃沿附近保持稳定即可。使用这种技术,每次只需要改变门的一个输入端来打开或关闭时钟就能保证电路的输出不含有任何毛刺或者尖峰脉冲了。

一文详解时钟门控(clock gating)
图4 基于锁存器的时钟门控

现在的芯片生产商会提供时钟门控的标准单元,为了DFT测试的需要,标准门控单元还会带着test_en这种输入信号,今天为了不跑题就不介绍相关内容了。

接下来就是架构师和逻辑设计工程师关心的问题了,怎么设计门控逻辑。在SoC设计中,可以实现三种粒度的时钟门控设计,

  • • 首先是粗粒度的设计,架构师要决定如何在时钟产生单元增加门控逻辑,根据SoC工作情况来判决是否关断某个时钟输出。这里提供一个思路,先根据功能划分出clock domain,然后再根据每个模块/IP之间的关系制定一张表,用于决定每个时钟域的开启和关闭状态。有了这张表就相当于有了一个状态机,根据状态机的当前状态决定时钟是否关闭。至于状态跳转的判决,可以是硬判决也可以是软判决。硬判决的好处是相对速度快;缺点是灵活性较差,而且设计相对复杂,往往需要模块/IP有接口信号可用。软判决刚好相反,优点是灵活性高;缺点是延迟比较大,不适于频繁开关,对于某些设计来说,实现软判决还要增加处理器,毕竟不是所有SoC都有CPU/MCU/DSP的。

  • • 其次是中等粒度的设计,模块设计师来决定是否关断内部子模块的时钟输入。这里没啥好说的,完全取决于模块的功能和实现方案了。

  • • 最后,可以在逻辑综合阶段,由综合工具自动插入门控单元。

前面两条依赖具体设计,最后一条不完全依赖设计,再多说几句。如果RTL代码写成下图左边的样子,在逻辑综合时不打开插CG的选项,综合出的电路如中图所示;而打开插入CG的选项,就会综合出下图右边的电路。由于CG单元本身也会产生功耗,一般一个CG单元后面要接多个寄存器才能达到节省功耗的效果。一般在综合时会通过选项选择3或4个。

一文详解时钟门控(clock gating)
图5 综合插入CG的示意图

对于综合工具,其插入CG的判定很简单,就是看有没有上图代码中的enbale逻辑。如果没有就不插。所以如果逻辑设计师想要写出满足低功耗需求的RTL代码,就要尽量在代码中使用类似上图的enable逻辑。

可能有喜欢刨根问底的同学要提问了“如果我的某段逻辑就没有enable怎么办?”这种情况下,可以试着向前或者向后找一找,有没有哪些逻辑可以借用过来。比如下图例子,绿色虚线代表可以增加的逻辑。RTL低功耗设计方法有很多,大家可以百度一下,或者等我以后写(此处有坑)。

一文详解时钟门控(clock gating)
图6 前向借用逻辑产生时钟门控信号

最后,要说明一个关于clock gating的误区。时钟门控固然可以节省功耗,但并不是越多越好。当CG cell达到一定数量时,再增加CG cell对功耗节省的效果就不明显了。

而且如前面所说,CG cell本身也是要产生功耗的,数量太多的话肯定要消耗不少,而且还会占用大量的面积,过犹不及。(再一次体现出做SoC的balance艺术,还是那句话,没有完美的SoC,只有完美的tradeoff)

一文详解时钟门控(clock gating)
图7 CG数量与节省功耗的关系

结束前总结一下,clock gating技术对整体SoC设计的影响(上一期DVFS忘了写,一并补充)。

| 低功耗技术 | 功耗
影响 | 时序
影响 | 面积
影响 | 架构
影响 | 设计
影响 | 验证
影响 | PR
影响 | |———— |————– |————– |————– |————– |————– |————– |———— | | CG | 中 | 大 | 小 | 小 | 小 | – | 小 | | DVFS | 大 | 大 | 小 | 大 | 中 | 小 | 小 | | | | | | | | | |

clock gating技术详解篇

当寄存器组的输出端没有驱动或没有变化时,可以关掉寄存器组的时钟来减少动态功耗,此谓门控时钟 (Clock Gating, CG) 技术。

最简单的一个带 EN 端的 D 触发器的 Verilog 逻辑描述如下:

always @(posedge CLK)
    if (EN)
        Q <= D ;

当不采用门控时钟结构时,DC 综合时会在触发器的输入端增加为带反馈端的多路选择器电路,如下图 (1) 所示。

当采用门控时钟结构时,DC 综合时仅会在触发器的时钟端增加一个时钟门控单元 (CG cell),而没有多路选择器结构,如下图 (2) 所示。

一文详解时钟门控(clock gating)
在这里插入图片描述

当多个寄存器组共用一个控制端时,结构上的优化尤为明显,如下图所示:

一文详解时钟门控(clock gating)
在这里插入图片描述

综上所述,门控时钟的优点有:

  • • (1) 寄存器时钟端翻转率降低,动态功耗降低

  • • (2) 时钟树网络开关率降低,动态功耗降低。

  • • (3) CG 扇出越大,结构上节省的选择器越多硬件资源消耗越少。      扇入:是指直接调用该模块的上级模块的个数。扇入大表示模块的复用程度高。 

          扇出:是指该模块直接调用的下级模块的个数。扇出大表示模块的复杂度高,需要控制和协调过多的下级模块;但扇出过小(例如总是1)也不好。

  • • (4) 相比于 PG (Power Gating),CG 结构相对简单,在综合时可自动插入。

产生门控时钟

产生门控时钟的条件为:

  • • 寄存器组共用同一个时钟;

  • • 寄存器组的控制端都是同步的;

  • • 寄存器组都是由同一个变量中推断而来的。

  • • 自动插入 CG

DC 综合时,使用以下命令与参数,设计中符合要求的寄存器便会被综合成带 CG 结构的触发器。

compile_ultra -gate_clk

DC 综合时插入的 CG 又分为离散的 CG cell 与集成的 CG cell (ICG)。离散的 CG cell 使用 Latch 与基本逻辑门单元组合而成,集成的 CG cell 是工艺厂家提供的一个带有时钟门控功能的特殊单元。

DC 中插入离散的 CG 命令为:

# 使用带 latch 结构的离散的 CG
set_clock_gating_style -sequential_cell latch

# 离散的 CG 中指定具体的 latch cell "lib_cell"
set_clock_gating_style -sequential_cell latch:lib_cell

DC 中插入没有 Latch 结构的离散 CG 时,命令如下:

# 使用或门逻辑,生成上升沿工作的寄存器的时钟门控
set_clock_gating_style -sequential_cell none -pos {or}

因为使用与门生成 CG 时在时钟上升沿容易出现毛刺,使用或门生成 CG 时在时钟下降沿容易出现毛刺,所以参数 -pos 一般配合 {or} 使用,-neg 一般配合 {and} 使用。

# 使用与门逻辑,生成下升沿工作的寄存器的时钟门控
set_clock_gating_style -sequential_cell none -neg {and}

假如 -sequential_cell 与 -pos/-neg 选项同时使用,那么两个选项指定的 CG 电路结构应该保持一致,例如:

set_clock_gating_style -sequential_cell latch -neg {latch and}
set_clock_gating_style -sequential_cell none -neg {and}

DC 中插入 ICG 时,命令如下:

# 使用集成的 CG cell
set_clock_gating_style -negative_edge_logic {integrated}
# 指定使用具体的集成 CG cell "lib_cell"
set_clock_gating_style -negative_edge_logic {integrated:lib_cell}

手动插入 CG

如果设置了自动产生时钟门控(-gate_clk),DC 综合时会对 RTL 设计中符合要求的寄存器进行时钟门控。但如果在 RTL 设计中,人为的编写时钟门控逻辑,DC 对此不会插入 CG ,如以下 Verilog 描述。

assign gated_clk = clk & en ;
always @(posedge gated_clk or negedge rstn) begin
    if (!rstn)
        data_out <= 8'b0 ;
    else 
        data_out <= data_out + 1'b1;
end

人为编写的时钟门控逻辑中,时钟很容易出现毛刺,增加了设计的不稳定性。

为了消除人为编写时钟门控逻辑带来的隐患,DC 中需要使用以下命令对手动编写的 CG 进行识别与替换。

replace_clock_gates

此命令实现的优化结果示意图如下:

一文详解时钟门控(clock gating)
在这里插入图片描述

禁止使用 CG

由于面积、时序等原因,需要禁止使用 lib 中的某一种 CG cell 时,可以使用以下命令:

#禁止使用指定的 CG cell:"lib_cell",
set_dont_use -power {lib_cell}

其中,-power 选项不可或缺,否则 ICG cell 的 dont_use 属性会被忽略。

门控时钟报告

可以使用以下命令,查看时钟门控单元的插入情况,以便确认是否需要对电路进行修改。

report_clock_gating

但是如果 RTL 设计中,存在人为例化的 CG cell,命令 report_clock_gating 是不能识别的,需要设置以下命令:

set power_cg_auto_identify true

毛刺的产生与消除

1 竞争与冒险

当一个逻辑门的输入有两个或两个以上的变量发生改变时,由于这些变量是经过不同路径产生的,使得它们状态改变的时刻有先有后,这种时差引起的现象称为竞争(Race)。竞争的结果将很可能导致冒险(Hazard)发生(例如产生毛刺),造成错误的后果,并影响系统的工作。

组合逻辑电路的冒险仅在信号状态改变的时刻出现毛刺,这种冒险是过渡性的,它不会使稳态值偏离正常值,但在时序电路中,冒险是本质的,可导致电路的输出值永远偏离正常值或者发生振荡。

避免冒险的最简单的方法是同一时刻只允许单个输入变量发生变化,或者使用寄存器采样的办法。

2.毛刺的产生与危害

信号在FPGA 器件中通过逻辑单元连线时,一定存在延时。延时的大小不仅和连线的长短和逻辑单元的数目有关,而且也和器件的制造工艺、工作环境等有关。因此,信号在器件中传输的时候,所需要的时间是不能精确估计的,当多路信号同时发生跳变的瞬间,就产生了“竞争冒险”。这时,往往会出现一些不正确的尖峰信号,这些尖峰信号就是“毛刺”。

下面具体看一下毛刺是如何产生的。如图为一个与门电路:

一文详解时钟门控(clock gating)
在这里插入图片描述

我们期望的设计是a和b信号同时变化,这样输出 OUT 将一直为 0,但是实际中OUT产生了毛刺,它的波形如下所示:

一文详解时钟门控(clock gating)
在这里插入图片描述

可见,即使是在最简单的逻辑运算中,如果出现多路信号同时跳变的情况,在通过内部走线之后,就一定会产生毛刺。而现在数字电路设计中的信号往往是由时钟控制的,如果将带有毛刺的输出信号直接连接到时钟输入端、清零或置位端口的设计,可能会导致严重的后果;此外对于多数据输入的复杂运算系统,每个数据都由相当多的位数组成。这时,每一级的毛刺都会对结果有严重的影响,如果是多级的设计,那么毛刺累加后甚至会影响整个设计的可靠性和精确性。

判断一个逻辑电路在某些输入信号发生变化时是否会产生毛刺,首先要判断信号是否会同时变化,然后判断在信号同时变化的时候,是否会产生毛刺,这可以通过逻辑函数的卡诺图或逻辑函数表达式来进行判断。

3.毛刺的消除

毛刺是数字电路设计中的棘手问题,它的出现会影响电路工作的稳定性、可靠性,严重时会导致整个数字系统的误动作和逻辑紊乱。

可以通过以下几种方法来消除毛刺:

3.1 输出加D触发器

这是一种比较传统的去除毛刺的方法。原理就是用一个D触发器去读带毛刺的信号,利用 D 触发器对输入信号的毛刺不敏感的特点,去除信号中的毛刺。在实际中,对于简单的逻辑电路,尤其是对信号中发生在非时钟跳变沿的毛刺信号,去除效果非常的明显。但是如果毛刺信号发生在时钟信号的跳变沿,D 触发器的效果就没有那么明显了(加 D触发器以后的输出 q,仍含有毛刺)。另外,D 触发器的使用还会给系统带来一定的延时,特别是在系统级数较多的情况下,延时也将变大,因此在使用 D 触发器去除毛刺的时候,一定要视情况而定,并不是所有的毛刺都可以用 D 触发器来消除。

3.2 信号同步法

设计数字电路的时候采用同步电路可以大大减少毛刺。由于大多数毛刺都比较短(大概几个纳秒),只要毛刺不出现在时钟跳变沿,毛刺信号就不会对系统造成危害了。因此一般认为,只要在整个系统中使用同一个时钟就可以实现系统同步。但是,时钟信号在FPGA器件中传递时是有延时的,我们无法预知时钟跳变沿的精确位置。也就是说我们无法保证在某个时钟的跳变沿读取的数据是一个稳定的数据,尤其是在多级设计中,这个问题就更加突出。因此,做到真正的”同步”就是去除毛刺信号的关键问题。所以同步的关键就是保证在时钟的跳变沿读取的数据是稳定的数据而不是毛刺数据。以下为两种具体的信号同步方法。

(1)信号延时同步法

信号延时法,它的原理就是在两级信号传递的过程中加一个延时环节,从而保证在下一个模块中读取到的数据是稳定后的数据,即不包含毛刺信号。这里所指的信号延时可以是数据信号的延时,也可以是时钟信号的延时。

(2)状态机控制

使用状态机也可以实现信号的同步和消除毛刺的目的。在数据传递比较复杂的多模块系统中,由状态机在特定的时刻分别发出控制特定模块的时钟信号或者模块使能信号,状态机的循环控制就可以使得整个系统协调运作,同时减少毛刺信号。那么只要我们在状态机的触发时间上加以处理,就可以避免竞争冒险,从而抑制毛刺的产生。

3.3格雷码计数器

对于一般的二进制或十进制计数器,在计数时,将有多位信号同时跳变。例如一个3bit二进制计数器,由’111’转换为’000’时,必将产生毛刺。此时,使用格雷码计数器将避免毛刺的出现,因为格雷码计数器的输出每次只有一位跳变。

参考资料

引用链接

[1] 毛刺的产生与消除: https://cloud.tencent.com/developer/article/1664949
[2] 一文详解门控时钟: https://www.elecfans.com/d/2045559.html


原文始发于微信公众号(TrustZone):一文详解时钟门控(clock gating)

版权声明:admin 发表于 2023年9月2日 上午7:10。
转载请注明:一文详解时钟门控(clock gating) | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...