Clifford论文系列多异步时钟设计的综合及脚本技术(2)
5.传递多个控制信号
在进行跨时钟域设计时经常犯的一个错误是简单的将多个控制信号从一个时钟域传递到另一个时钟域,而忽略了控制信号排序的重要性。简单地在所有控制信号上使用同步器并不总是足够好的。如果控制信号的顺序或对齐是重要的,必须注意将信号正确地传递到新的时钟域。
1.同时需要所有的控制信号
也就是说,所有跨时钟传递的控制信号都要同时到达。在下图所示的示例中,新时钟域中的寄存器需要负载信号和使能信号才能将数据值加载到寄存器中。如果负载信号和使能信号都是从一个时钟域发送的,那么这两个控制信号之间的小偏差就有可能导致两个信号到达目的时钟域时属于不同的时钟周期,这个就有可能导致电路不工作,例如在本例中,就会导致寄存器中的数据不被加载。
为了解决上述问题,方法是在跨时钟域传递前先把所有的信号进行合并,变为一个信号,这样可以消除控制信号移位的可能性,如下图所示。
2.需要按顺序连续传输控制信号
下图中的关系图显示了两个enable信号,aen1和aen2,它们作为控制信号,用于通过短流水线设计中支持数据信号的顺序传递。问题在于,在源时钟域ben1控制信号的下降沿可能稍微在控制信号ben2的上升沿之前一点点。换句话说,控制信号ben2并没有完全按照理想的情况传输,那么在目的时钟域可能就可能导致控制信号aen1和aen2由于这轻微的时间差距,导致使控制信号多了一个时钟周期的间隔。这将导致a2输出信号被第二个触发器错过。
这个问题的解决方案是,在跨时钟域传输时,先把信号合并,只传递一个信号,然后在目的时钟域生成第二个顺序控制信号。如下图所示:
3.多编码控制信号的传输
下图表显示了在时钟域之间传递的两个编码控制信号。如果两个编码的信号在采样时有轻微的偏差,就会在新的时钟域中产生一个错误的解码输出。
这个问题和第一个问题类似,问题在于这个信号不能进行合并。因为每个数据位都有用,有特定的含义。对于这个问题的一个解决方案是,原时钟域在发送完编码控制信号的下一个时钟周期必须产生一个使能信号,并且在编码控制信号失效前的一个周期去除使能信号。也就说,要保证使能信号存在的时间长度比目的时钟域的时钟周期要长一点。
上述方法能保证,在最坏的情况下,当编码信号被目的时钟域采样时,使能信号同时目的时钟域的时钟采样,或者当编码控制信号失效时,使能信号也会同时失效。而在最好的情况下,编码控制信号会在使能信号之前一个周期被目的时钟域域采样,并且在使能信号失效一个周期后,编码控制信号才会失效。这个方法可以保证编码信号在使能信号有效期间一定是有效的。
这个问题的第二个解决方案是首先就在原时钟域进行解码操作,然后把解码得到的值通过同步器传递给目的时钟域,在这儿需要注意的是,对于解码器来说,一般解码后只会存在一个值为高。在目的时钟域中,利用一个有效状态机去判定是否有新的译码输出有效。如果没有新的译码输出,那么就意味着原来的译码输出已经失效,新的译码输出即将到来。如果同时有两个译码输出,则最后一个译码输出信号将导致状态机改变状态,而较老的译码输出信号将在新时钟域中的下一个上升时钟边缘处关闭。不过在这需要注意的是,必须保证译码输出信号存在的时间比较长,比目的时钟域的时钟周期长很多才可以。
6.数据传输
将数据从一个时钟域传递到另一个时钟域是在时钟域之间传递多个随机变化的信号的一个例子。使用同步器来处理数据的传递通常是不可接受的。使用同步器错误地采样多位数据更改的机会太多了。
在时钟域之间同步数据的两种常用方法是:(1)使用握手信号在时钟域之间传递数据;(2)使用FIFOs(先进先出存储器)使用一个时钟域存储数据,使用另一个时钟域检索数据。
1.时钟域之间的握手数据
可以使用两个或三个握手控制信号在时钟域之间传递数据。当涉及到握手时,使用的控制信号越多,从一个时钟域向另一个时钟域传递数据的延迟时间就越长。使用握手的最大缺点是传递和识别每个传输的数据字的所有握手信号所需的延迟。
2.异步FIFO设计
7.仿真问题
正如在前面提到的,信号通过同步器跨越时钟边界将经历建立时间和保持事件的违例。这就是为什么要在设计中加入同步器,以滤除信号的亚稳态效应,因为信号的变化太接近目的时钟域时钟信号的上升边缘。在进行跨时钟域门级仿真时,ASIC库中的触发器模型通过设计建立时间和保持时间表达式来匹配实际触发器的时序规范。ASIC库通常对触发器进行建模,在发生时序违例时驱动触发器输出上的X(未知数)。在仿真门级同步器时,建立时间和保持时间违例可能导致ASIC库发出建立时间和保持时间错误消息,违例信号常常被驱动到X值。当试图验证整个门级设计的功能时,这些x值会传播到设计的其余部分,从而导致问题。大多数Verilog仿真器都有一个命令选项来忽略所有的时序检查,但是这也会忽略其余设计所需的时序检查。
用户可以把ASIC库中用于同步器的触发器的建立时间和保存时间设定为零,但是这会导致所有的由相同类型的触发器组成的电路的建立时间和保持时间都变为零,包括后续设计中的电路。
当然,可以把同步器中需要的触发器从ASIC库中复制一份到新的库中存储,并把新的库中的触发器的建立时间和保持时间设为零。然后改变门级网表文件,取代原来的同步器。但是这同样是一个容易出错的过程,可能需要重复每次新生成网表或它可能要求创建makefile和脚本,以便在每次生成新netlist时自动进行修改。
一个好办法是使用Synopsys命令只修改设计中的第一级触发器的建立时间与保持时间的SDF反标文件。SDF文件是基于实例的,因此针对问题单元的建立时间和保持时间更容易实现。与手动删除SDF文件中的建立时间和保持时间不同,更好的方法是将SDF文件中只针对违例的错误情况,将现有的建立时间和保持时间替换为零。
设置保持时间为零意味着不存在时序违例,因此不会有未知信息传播到设计的其余部分。下面是Bhatnagar给出的dc_shell命令,用于建立时间和保持时间为0:
setannotatedcheck 0 -setup -hold -from REG1/CLK to REG1/D
8.结论
综合工具在同步设计上做得最好。时序分析工具被设计用来报告时钟同步设计中的时序问题。综合脚本很容易为单时钟同步时钟设计创建。为了使得多时钟域设计更像同步时钟,主要方法如下:
划分非同步块,使每个模块只有一个时钟,通过创建时钟域子块,可以方便地验证时序,而静态时序分析工具可以更容易地验证这些子块。
对同步器块进行分区,以允许来自有且仅有一个时钟域的输入,并仅使用一个异步时钟对信号进行计时,从而创建可管理的同步器子块,这些子块也可以方便地对其进行计时。
面向时钟的命名约定可以帮助识别需要在不同异步时钟域中计时的信号。
欢迎点赞,关注,分享~~, 本文原发于微信公众号【数字ic小站】