什么是亚稳态?
对大多数工程师来讲,亚稳态是非常难以追踪的,因为它具有不确定性,在相对规范的设计下,如果仍然发生这个问题,那么可能非常难以复现异常。简单来讲,当触发器不满足建立时间和保持时间要求时,就会导致亚稳态。亚稳态出现时,触发器既不是高逻辑也不是低逻辑,后续电路则可能读取为0或者1(不确定状态),导致电路逻辑做出不符合当前事物逻辑的事情。
对于数字设计人员来讲,只要信号从一个时钟域跨越到另一个时钟域,那么就可能发生亚稳态。我们称为“跨时钟域”即“Clock Domain Crossing”,或CDC。
所以今天主要简单了解如何处理CDC这些基础问题。
同步跨时钟域信号
对大多数初学者来讲,当我们遇到CDCs时,有经验的工程师会告诉我们“打两拍”,即让信号通过两个 flip-flops,每个flip-flop都由新时钟域的时钟驱动(如下图)。第一个触发器出现亚稳态的概率很高,但第二个触发器的输出亚稳态的概率就会低得多。当然更多的flip-flops会让亚稳态的概率进一步下降,但一般下降的概率差距不会太大,如何选择取决于设计者自己。但并非多数CDC问题都能用这种简单方法,这种设计适用于旧时钟域比新时钟域慢的多的情况。经典的可配置的代码如下。
异步复位同步释放
CDC中一个常见的例子就是异步复位,这个问题我在“FPGA复位信号设计讨论“一文中有详细的表述,这里简单讲解,对于初学者而言,不太建议用异步复位,尽管他们各有优劣,但至少对FPGA设计者而言,这个建议应该是有效的,即使是Xilinx官方也同样建议使用同步复位(UG949)。 但有些状态下可能同步复位无效,比如在低功耗设计中,时钟可能在复位前就已经被“无效”,那么异步复位自然成为一个选择。异步复位关键点不在进入复位状态,而在于移除复位,因为移除状态可能会进入亚稳态,除了“FPGA复位信号设计讨论”一文,大家同样可以参阅我翻译的经典论文“同步复位与异步复位”。经典的代码如下所示,但请注意区别此处代码和“打两拍“的区别。
很多人争论高电平复位有效好还是低电平复位有效好,一般情况下我常见低电平复位有效,但高电平复位有效也不是没有,一般认为在FPGA中区别不是太大,但在ASIC中,低电平似乎更加常见。
跨时钟握手
有时需要一种方法来处理CDC,例如从慢时钟到快时钟,从快时钟到慢时钟,这时需要:握手信号,在“AXI4协议逻辑规范以及BUG处理”一文写过握手的注意点。握手的详细技术点感兴趣的朋友可以网上找相关资料。
FIFO
FIFO网上的文章特别多,具体的设计细节有很多需要讨论的地方,但对于跨时钟域而言,FIFO几乎是最方便的数据传输方式。这里不展开讲,之前我写过关于FIFO的相关文章,不是特别详细,接下来会有详细的关于FIFO的计划,在此之前,大家可以看Clifford E. Cummings经典论文,他的论文真的很推荐。