时钟切换

279 阅读3分钟

刚入行时最早看到的时钟切换电路出自下面这篇文献,第20页,Trouble-Free Switching Between Clocks。 这篇极短的小文章可能是 Xilinx 元老 Peter Alfke 写的。 Peter 是我非常敬重的前辈,读过几篇他写的数字电路小文章,非常实用,受益匪浅。

www.xilinx.com/publication…
在这里插入图片描述
这个电路虽然概念上是对的,但有明显瑕疵。 如果 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 同步而已。
在这里插入图片描述
在这里插入图片描述
这个改进电路依然有一些不够完美的地方。 譬如电路中的 AND换成 ICG 会更好一些,对后端的工具更友好一些。以后再讨论吧。

以上是一个比较经典的时钟切换电路。 根据实际使用场景的不同,时钟切换有很多不同的实现方法,都可以做得非常经典。 时钟,复位,是数字设计里最最基本的电路,稍有不慎,就会毁了整个设计,一定要谨慎再谨慎。

顺便讲一下,在芯片设计里,这种特殊电路都应该是例化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,会复杂一些。