异步时钟同步的问题(转)
http://blog.csdn.net/lureny123/article/details/12907533
很久不写东西了,因为这个空间里似乎都是做软件的,而我把ASIC/FPGA认为是硬件电路。所以写的虽然也是代码,但是想的确实硬件电路。这让我在这个软件人员居多的空间里显得格格不入。
写这个题目,其实是我有些忍不住了。这十几年来,我面试过很多新人,也带过很多新人,他们之中很多人的成就都已经超越了我。但是当我们偶尔回顾这个小小的跨越时钟域的问题时,仍然有很多的困惑和不理解。
我喜欢用这个题目作为我的面试题目,因为它不是一个简单的题目,而是涉及到ASIC设计本质的题目,如果细细研究起来,还非常复杂。写这个东西,希望所有在做ASIC的人,能从一个更高的角度去审视它,并且能因此更深刻的体会做ASIC的严谨。
言归正传:
题目:单根信号线,跨越时钟域,该怎么处理?
1。 首先给一个最简单的答案: 用寄存器打两拍
这里其实有一个很本质的问题需要讨论,就是为什么要所存两拍? 把这个问题插进来说说吧。所有做ASIC的人,都要面对两个基本的概念:setup time 和 hold time。如果寄存器不满足这两个时间,将会出现亚稳态。很多新人以为亚稳态仅仅是逻辑上的障碍,其实亚稳态是实实在在的电路上的问题。
模拟电路中,三极管主要工作在其放大区间,而在数字电路却是要工作在截至态。亚稳态非常类似模拟电路中的放大态,这个状态将使得器件的输出电流被放大,如果这个状态被传递,那么将导致更多的电路处在放大电路的工作状态中,这将引起巨大的电流和功耗,甚至烧毁芯片,所以,跨时钟域是一定会出现亚稳态的,但是我们必须要把亚稳态控制在一个很小的范围内。这就是为什么要在其后面再用一个寄存器的原因。它的功能就是把亚稳态仅仅限制在那一个寄存器的小区域。
好了,继续说逻辑上的事情。这个两拍的电路很显然,只适合信号从低频时钟跨越到高频时钟,那么当高频时钟要跨越到低频时钟该怎么办呢?
2. 高频信号要进入低频时钟域,最原始的想法就是 展宽。如果我们知道这两个时钟之间的频率差别,那么用一个计数器去将高频信号做适当的展宽,使其宽度大于低频时钟的一个周期,然后就可以继续用上述的方法跨域时钟域了。
这种方法的本质,是降低时钟频率,是把高频时钟产生的信号先做了频率的降低,降低到比原来的低频时钟还要低,因此当然就可以用第一种方法了。
那么,如果我们不能在设计的最初就知道彼此的频率差异,该怎么办呢? 通常这个问题,都会让面试者陷入绝境。
3. 仍然是高频时钟域的信号要进入低频时钟域,但是我们不能确切的知道两个时钟频率到底差异多少,这时,我们的基本思路还是展宽,只是这个展宽要做成一个能自动适配的功能,当然,这就需要做反馈。我是学自控的,反馈,我很熟悉。
这里面其实是3组寄存器,reg-1和reg-2是clk-a的时钟域,其中reg-2的功能就是要把高频时钟clk-a产生的信号根据clk-b的频率来做展宽。
reg-3和reg-4是两个寄存器,用来把clk-a的信号跨时钟域到clk-b中。
reg-5和reg-6其实也是两个寄存器,用来把clk-b时钟域的信号跨越到clk-a,这个信号将作为一个反馈信号,来实现展宽的逻辑,实现这个逻辑的,主要是那一个与门和一个或门。
具体的逻辑就不说了,只说说思想:这是一个逻辑反馈电路,和模拟电路中的电压跟随电路的思考方式不太一致。它的思考逻辑是,如果输出还没有得到逻辑1,那么输入的逻辑1就要保持。但是我们很容易就看出来了,这个电路仅仅可以把一个 高电平脉冲 展宽。那么如何将一个低电平展宽呢?其实简单的调整一下那个与门和或门的电路就可以了:
但是这仍然不是一个完全意义上的跨越时钟域的逻辑。那么能不能做一个完整功能的电路呢?这就要考虑如何把上述这两种展宽逻辑融合到一起。
4. 融合这两个电路,就必须先从原理上说清楚一件事情:低频时钟是无法完全去采样高频信号的,这里面一定会丢失信息。这是无法避免的。
如果reg-2的输出是1,那么我认为目前正在把逻辑1展宽,如果当前reg-2的输出是0,那么我认为正在把逻辑0展宽。至于短时间内频繁的出现逻辑1和逻辑0,那么很可能会丢失某些状态,这也是我们上面说到的,不可避免的问题。
说到这里,是不是所有的事情都说完了呢?还没有,至少我们的思考还不应该结束。
5.如果一个信号需要跨越时钟域,但是我们不知道哪个时钟快,哪个时钟慢,该怎么办呢?
呵呵,太忙了,该开会了,谁有好办法,不妨试试看吧。
我等着所有的奇思妙想。