热度 37| |
刚入行时最早看到的时钟切换电路出自下面这篇文献,第20页,Trouble-Free Switching Between Clocks。 这篇极短的小文章可能是 Xilinx 元老 Peter Alfke 写的。 Peter 是我非常敬重的前辈,读过几篇他写的数字电路小文章,非常实用,受益匪浅。
https://www.xilinx.com/publications/archives/xcell/Xcell24.pdf
这个电路虽然概念上是对的,但有明显瑕疵。 如果 Select 相对于 Clock A, Clock B 是完全异步 asynchronous,电路中的两个 flip flop 在 Select 变化时会有亚稳态 metastability的可能性。 克服这个瑕疵的 fix 很简单,把图中的单个 flip flop 换成两级 flip flop 组成的同步器 synchronizer 就可以了。
Xilinx这个电路的基本思想是 SR latch。 去掉图中两个 flip flop ,最前端的两个 AND 组成一个类似 SR latch 的电路,只不过 SR Latch 的 S,R 输入换成了 Select 和 Select inverted。 为了使 SR Latch 的输出能与所需控制的时钟同步,加上了一级 flip flop 同步一下。 当然,两级 flip flop 同步会更好。Xilinx这个电路里有一个非常重要的小细节,牵涉到时钟切换的一条重要原则 --- 先关断当前选择的时钟,再使能新选择的时钟。 QB 反馈到 Clock A 那边经过一个反向再和 Select 反向 AND,QA 反馈到 Clock B 那边经过一个反向再和Select AND,保证了先关断再使能这个重要原则。
Xilinx这个电路里还有个非常重要的小细节,也是该电路的精妙之处。 这两个 flip flop 的时钟输入端有个小泡泡,意思是时钟下降沿触发。这是一个重要的设计思想。如果要 gate off 掉一个时钟,在该时钟低电平时gate off 是最安全的。 如果是在高电平时做切换,很容易造成高电平被切掉一段变成一个毛刺,这可是大大的危害。 搞笑的是网上 随便搜一下 “glitchless clock switching”,会出来一大堆文章,虽然都是基于Xilinx这个电路,但大部分漏掉了低电平触发这个细节。没有完全理解就胡乱抄胡乱吹牛,比较符合南亚某大国的国民性格。嘴上吹得天花乱坠,做事毛毛躁躁。做出来的电路有时工作有时不工作。玩具上用用倒也没大问题。 这种态度用到飞机上就是 737 MAX。
下面是改进的电路,一级 flip flop 换成了两级 flip flop 同步而已。
电路启动波形
切换波形 – fast to slow
切换波形 – slow to fast
这个改进电路依然有一些可以变化的地方。 譬如电路中的 AND换成 ICG 貌似更好一些,对后端的工具更友好一些,实际上ICG在初始状态有一个额外要求,不见得是好的选择,见补充2。
以上是一个比较经典的时钟切换电路。 根据实际使用场景的不同,时钟切换有很多不同的实现方法,都可以做得非常经典。 时钟,复位,是数字设计里最最基本的电路,稍有不慎,就会毁了整个设计,一定要谨慎再谨慎。
顺便讲一下,在芯片设计里,这种特殊电路都应该是例化instantiate 的。 例化的好处是便于在后端流程里找到这些门。例如,这里的AND 可以用一个 bbox_and 模块。bbox_and 里例化 instantiate 库里的 CKAND2 门。时钟切换电路里例化 bbox_and 模块,给个 u_bbox_and_1 这样的 instance name。 在后端设计里,就可以很方便找到 u_clkgen/u_bbox_and_1/bbox_and_0 ,加约束就会很方便。 使用 bbox 模块也是数字设计中一个重要技巧,以后有时间再讨论了。
小结一下。
1) 时钟切换的重要原则 --- 先关断当前选择的时钟,再使能新选择的时钟。
2) 当前时钟低电平时切换是比较安全的做法。
补充一下。 上面的电路只是概念上的示意图。 实际设计中要考虑 DFT, 要加 DFT clock mux, DFT reset mux,会复杂一些。
补充2
前面讲了可以考虑把AND换成ICG。一位网友指出,换成ICG后如果时钟的初始值时高电平,电路可能会出问题。 首先感谢这位网友,谢谢指出这个与ICG特性有关的重要问题。
下面是改用ICG后的时钟切换电路。
下面是在clk1, clk2初始值都为高的场景下该电路启动时的仿真波形。在这个特殊场景下,由于clk1, clk2初始为高,使得对应的ICG输出clk_slow_gated, clk_fast_gated初始值为X,造成切换电路输出在初始时也为X!造成这个现象的是ICG的一个重要“缺陷” – 未被初始化uninitialized ICG。
解释这个现象,首先要先看一下这个电路里用到的ICG的内部构造。这里SE(scan mode ICG enable),E(functional mode ICG enable)是latch的数据输入。Latch的gate信号为CK的反向。
CK为0时latch打开,(E | SE)通过latch,ICG的输出 = (E|SE)& CK。因为此时CK为0,ICG的输出也为0。
CK为1时latch关闭并保持以前的状态(latch_old_state)。假设CK变为1前E=1,latch_old_state =1,ICG的输出=latch_old_state & CK= CK;假设CK变为1前E=0,latch_old_state =0,ICG的输出=0 & CK= 0。
如果初始时CLK为1,ICG内部的latch是关闭的,E无法通过,而且因为之前latch从来没有打开过,没锁存过任何确定的值,latch_old_state 不确定 (仿真中显示为X)。在这个场景下ICG输出= latch_old_state & CK= X& CK= X,即ICG输出为X。下面就是这个场景的波形。
如果初始时CLK为0,ICG内部的latch是打开的, ICG的输出为 (E & CLK) = 0,ICG输出为确定值,ICG被成功初始化。下面是这个场景下的仿真波形。
综上所述,为了避免上述ICG未初始化引起的问题,使用ICG搭时钟切换电路时,系统设计中要考虑加一个时钟初始为0的要求。
补充3
基于补充2的电路,还有一种变化,就是把falling edge DFF换成rising edge DFF。这时要特别小心两个时钟周期相差很大的情况。例如一路时钟为clk_slow (slow clock), 另一路为clk_fast (fast clock),选择信号sel由0变1 (clk_slow to clk_fast switch)。当clk_slow上升沿到来,当clk_slow这一路第二级DFF的输出 (sel_sync_slow) 变为0时,并不意味着clk_slow对应的ICG输出立刻变0,而是要等到clk_slow下降沿到来。也就是说此时clk_sw的输出仍旧clk_slow的高电平。这时如果clk_slow第二级DFF输出(sel_sync_slow) 被直接送到clk_fast的选择输入逻辑,如果clk_fast非常快,就会出现clk_slow ICG尚未关断,clk_fast ICG已经打开,造成切换后的输出clk_sw出现毛刺。
为了避免这样的情况,必须引入第三级DFF。ICG E仍旧用第二级DFF输出,第三级DFF输出送到另一路选择逻辑。 整体来看这样的电路有点浪费资源。
补充4
上面几种电路都只能在时钟正常跑起来的情况下完成切换。如果当前选中的时钟停了,选择信号无法通过由当前时钟驱动的两级DFF,也就无法实现切换了。
时钟停止属于系统级错误,需要在系统设计找到解决方案,这里就不赘述了。
andywang3791: Jake 请问后端对bbox_and_0会做什么特别的约束呢
jake: 为了避免工具把 AND gate 优化掉,一般加上 dont_touch。 我个人偏好 preserve 而不是 dont_touch。 这样工具可以根据 loading 选择 AND gate 的 drive strength ...
andywang3791: preserve是否就是DC里的set_size_only,只可以让工具改size,jake 请问这里的AND gate出为何不需要check gating time,我理解这里同步器输出后<半个T就是在做ga ...
jake: 是的,OR 肯定不需要,也应该加上 set_disable_clock_gating_check。
电路里控制信号是时钟下降沿出来的,因为 clock to output delay,控制信号会滞后于时钟。 ...
andywang3791: 有些疑问,对于AND gate的gating check,setup check需要gating信号在clk上升沿之前,hold check需要gating信号在下降沿之后,clk到q有output delay,但是clk到 ...
andywang3791: 有些疑问,对于AND gate的gating check,setup check需要gating信号在clk上升沿之前,hold check需要gating信号在下降沿之后,clk到q有output delay,但是clk到 ...
jake: 更新 -- 抽空做了试验,Innovus 19.1*,不需要加 set_disable_clock_gating_check,工具可以完美理解同步器到 AND 这条路径,甚至连 OR 也不需要加 set_disable_ ...
andywang3791: Jake, 疑惑为何OR上也不需要加呢
jake: Genus, Innovus 现在都能很好地 trace clock path。 工具能自动理解 clk1 经给 AND gate 后到达 OR 的一端,另一端是 clk2 经给 AND gate。 工具正确理解经过 O ...
andywang3791: Hi Jake,请教下,SOC里两个OSC切换,一个是RC,一个是XTAL,默认是RC,如果要切换到XTAL,想法是先enable XTAL,然后计数计到一定值输出stable,软件check之后再 ...
andywang3791: hi jake,请问对于两个异步时钟的glitchfree clock mux后是否要create 两个generated clock
jake: 为了避免工具把 AND gate 优化掉,一般加上 dont_touch。 我个人偏好 preserve 而不是 dont_touch。 这样工具可以根据 loading 选择 AND gate 的 drive strength ...