芯片设计中常见的跨时钟处理错误及解决方法
2023-07-09孙远航李彧倪晓波孙增振
孙远航,李彧,倪晓波,孙增振
(网络通信与安全紫金山实验室,江苏南京,211100)
0 引言
随着芯片的集成度的提高,其接口种类越来越多功能也变得越来越强大。近年来芯片设计越来越复杂,突出表现为时钟越来越快,时钟域多,跨时钟交互越来越复杂。如果这些跨时钟CDC(Clock Domain Crossing)的地方处理得不当,那么对于整个芯片来说可能是灾难性的。而随着近年来芯片研发的成本越来越大,其所造成的经济损失也是非常可观的。所以这就使得在芯片设计时必须很谨慎地去分析与对待异步信号跨时钟域的问题,在设计时就将问题考虑充分,避免这类问题影响芯片整体的功能及可靠性。本文重点介绍几种典型的CDC 处理错误,并给出相应的处理方法。
1 亚稳态与常见的处理方法
1.1 亚稳态分析
亚稳态指的是触发器无法在一个规定的时间达到一个确定的状态,当触发器进入亚稳态,我们既无法预测其输出的电平,也无法预测其何时才能稳定地输出正确的电平[1]。
在亚稳态期间,触发器输出一些中间级电平,并且这种电平可以延通路传播,如图1(a)所示,其产生的原因是由于信号在时钟触发沿的判决窗口没有保持稳定,导致触发器中锁存信号的电容充电不足,从而使得触发器需要花很长的时间才能使输出信号达到标准电平,使电路“反应”变迟钝。同步器是处理 CDC 问题时所采用的主要器件,其通常由两个级联的触发器组成[2~3],如图1(b) 所示。
图1 亚稳态及同步器示意图
1.2 常见的跨时钟处理方法
常用的CDC 处理方法,分别是信号同步器[4]、多周期路径MCP(Multi-Cycle Path)同步法、握手协议[5~6]以及异步FIFO[7~9]。
这4 种信号跨时钟域的方法在我们的设计中都有使用,具体使用哪一种方法需要对应具体情况进行分析,在对于跨时钟信号是单bit 信号的时候推荐使用信号同步器来实现;在对应跨时钟信号是总线仲裁类或者缓变化bus 型数据时推荐使用多周期路径同步法或者握手协议来实现;当需要跨时钟的是主数据路径时,例如一些接口协议需要做速率四配时,推荐使用异步 FIFO 来处理[8~9]。
2 常见的 CDC 处理错误及解决方案
前面一节主要介绍了一些信号数据跨时钟的方法,下面介绍一些在设计中常见的跨时钟处理错误,并分析其错误的原因和改正的方法[8~9]。
2.1 组合逻辑输出跨时钟
组合逻辑输出容易由于竞争现象等原因出现毛刺,而这些毛刺再经过同步器跨时钟处理时可能会导致一些逻辑功能上的错误,如图2(a)所示。比较好的处理方式是先将信号进行组合处理之后再用寄存器在源时钟域下将数据拍出,保证数据进入同步器之前的路径是“干净”的。如图2(b)所示,这样就可以避免毛刺对同步器造成不好的影响。
图2 组合逻辑跨时钟处理
2.2 同一信号在多处作跨时钟处理
在设计中有时会对同一个信号在多处作跨时钟处理,这是非常危险的。表面上看每一路同步路径都是安全的,但是由于需要跨时钟的信号扇出到不同同步器之间的走线延时不一致,如图3(a)所示,td这个延时会导致同样的一个信号到达不同同步器第一级寄存器的时刻不一致,便导致不同同步器第一级寄存器是否会进入亚稳态的不确定,以及从亚稳态退出时输出的信号电平值不确定。这与我们的设计预期是不一致的,如果忽略了这种潜在的威胁,那么对我们设计的功能可能会产生不良的影响。特别是对于一个要扇出到多个子系统的异步信号来说,这种同步后的不确定性可能会导致子系统对同一信号的处理存在差异导致整个系统的功能错误,并且这种错误在实际定位时是很难被定位到,也是很容易被忽略的。
图3 同一信号在两处作跨时钟处理
解决这类问题的方法是,对于多个子系统都可能用到的异步信号在一个地方统一作跨时钟处理。然后再将这个同步过的信号扇出到多个模块中去,这样就能够保证多个子模块中所用到的跨时钟信号是同步的,保证功能的同步性,如图3(b)所示。
2.3 信号跨时钟后有逻辑耦合
信号跨时钟后有逻辑耦合,这类问题在我们的设计中也时有出现,如图4(a)所示。其带来的主要影响和上一类问题类似,两个异步信号在做完跨时钟处理之后他们之间的时序关系有可能与我们预期的不一致,从而导致功能上的错误,所以这类问题在我们的设计中也应该避免。
图4 信号跨时钟后有逻辑耦合
图5 全握手协议
其解决方法是首先在异步时钟域中将相互有逻辑关系的信号“合并”为单 bit 信号,再将这个单bit 信号做跨时钟域处理如图4(b)所示。
2.4 握手协议中请求与响应路径寄存器级数不一致
握手协议是处理总线类信号跨时钟域的方法之一,这种方法的优点是结构简单且十分安全,收发侧都要根据对端发出的请求或响应信号来进行bus 型信号跨时钟域处理。如图5所示全握手协议的演示过程[6]。
全握手协议的特点是,在收发两端在发送请求或者终止请求之前都需要等待对端的回应。全握手协议在异步数据跨时钟的安全性能方面很强健,因为通过检测请求与响应信号,每一侧电路都清楚地知道对端的状态。但是这种方式也有其不足,那就是完成所有交互的整个过程要花费很多长钟周期,数据信号跨时钟的延时比较大。所以在具体使用时会对握手路径进行“优化”,减少反馈路径的寄存器级数是一种优化方法,如图6 所示,其中反馈路径迁移一级,减少了反馈路径的延时。但是这种优化是存在局限性的,那就是发送侧的时钟频率必须小于接收侧时钟频率。如果接收侧时钟频率大于接收侧的3 倍以上则会出现接收侧还未将数据总线上的数据采样发送侧就将数据更新覆盖的情况。类似的这些问题在设计和优化CDC 路径时很容易被忽视的。这就需要我们在写代码之前仔细分析CDC 路径并且考虑所设计的方法对两端时钟频率是否敏感,如果所设计的方法对于应用场景有特定的限制那么在代码中也应该有相应的注释,以防止后面别人改写代码时没有考虑全面导致功能错误。
图6 握手协议反馈路径“前移”
3 对CDC 信号处理的一些建议
3.1 对CDC 信号进行有效的标识
对于一些异步时钟以及跨时钟的数据、地址以及使能信号在命名时要明确的显示出其所在的时钟域,例如mac_clk、pcs_clk、mac_data,mac_addr 等。
3.2 尽量做到每个module 中只使用一个时钟
这样做的好处是在使用一些静态时钟分析工具时可以更方便快捷的进行时序分析。当然这个建议也是相对性的,比如一些top 级的模块不可能做到完全一个时钟域。
3.3 对 CDC 信号进行分类
在设计中要对所涉及的CDC 信号进行分类,它们是多bit 还是单bit;多bit 是否能化简合并为单bit;是控制信号还是数据信号;对两侧时钟频率变化是否敏感;跨时钟数据是缓变的还是突发的等等。划分得越细越好,对于这些不同种类的CDC 信号采取相对应的方法进行处理。
3.4 谨慎对待继承下来的代码
从前面提到的对握手协议优化的案例可以看出,对CDC相关的代码进行继承和优化时需要特别的谨慎,因为如果使用环境的大前提发生了变化(例如跨时钟场景从慢到快变为从快到慢)可能会造成继承或优化的代码无法达到设计的预期。
4 结束语
本文主要介绍了 RTL 设计中的 CDC 问题,分析了亚稳态产生的原因以及解决的方法。重点介绍了在设计中常用的4 种信号跨时钟的处理方法,并分析了一些设计中处理异步信号时常见的错误并给出了相应的改进意见,最后给出了几个处理CDC 信号的实用建议。CDC 问题在设计中虽然不起眼,但是业界中很多失败的案例都是由它引起的,特别是现在先进设计中可能会用到先进工艺、逻辑规模又异常大,从而导致成本非常高。同时也正是由于这些问题不起眼,在验证与时序分析阶段有时很难定位和发现这类问题,所以对于RTL 开发来说,作为芯片设计的最前端应该把这类问题消灭在源头,这对于时间和成本来说都是最划算的。