同步世界中的异步信号

只有最初级的逻辑电路才使用单一的时钟。大多数与数据传输相关的应用都有与生俱来的挑战,即跨越多个时钟域的数据移动,例如磁盘控制器、CDROM/DVD 控制器、调制解调器、网卡以及网络处理器等。当信号从一个时钟域传送到另外一个时钟域时,出如今新时钟域的信号是异步信号。 网络

在现代 ICASIC 以及 FPGA 设计中,许多软件程序能够帮助工程师创建几百万门的电路,但这些程序都没法解决信号同步问题。设计者须要了解可靠的设计技巧,以减小电路在跨时钟域通讯时的故障风险。异步

异步时钟基础: 函数

从事多时钟设计的第一步是要理解信号稳定性问题。当一个信号跨越某个时钟域时,对新时钟域的电路来讲它就是一个异步信号。接收该信号的电路须要对其进行同步。同步能够防止第一级存储单元(触发器)的亚稳态在新的时钟域里传播蔓延。 工具

亚稳态是指触发器没法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚稳态时,既没法预测该单元的输出电平,也没法预测什么时候输出才能稳定在某个正确的电平上。在这个稳按期间,触发器输出一些中间级电平,或者可能处于振荡状态,而且这种无用的输出电平能够沿信号通道上的各个触发器级联式传播下去。spa

 

    对任何一种触发器,在时钟触发沿先后的一个小时间窗口内,输入信号必须稳定。这一时间窗口是多种因素的函数,包括触发器设计、实现技术、运行环境以及无缓冲输出上的负载等。输入信号陡峭的边沿能够将此窗口减至最小。随着时钟频率的升高,会出现更多有问题的时间窗口,而随着数据频率的提高,这种窗口的命中几率则会增长。 FPGA 制造商和 IC 晶片厂用“MTBF”来标识合格的触发器,而且肯定它们的特性。“MTBF”(平均无端障时间)用统计方法描述了一个触发器的亚稳态特性,即肯定某个触发器出现故障的几率。在计算 MTBF 时,制造商部分基于输入信号改变致使触发器不稳按期间的时间窗口长度。另外,MTBF 的计算还使用了输入信号的频率以及驱动触发器的时钟频率。 设计

在一个 ASIC 或 FPGA 库中,每种触发器都有时序要求,以帮助你肯定容易出问题的窗口。“创建时间”(Setup time)是指在时钟沿到来以前,触发器输入信号必须保持稳定的时间。“保持时间”(Hold time)则是指在时钟沿以后,信号必须保持稳定的时间。这些指标一般比较保守,以应对电源电压、工做温度、信号质量以及制造工艺等各类可能的差别。若是一个设计知足了这些时序要求,则触发器出现错误的可能性能够忽略不计。 指针

现代 IC 与 FPGA 设计中使用的综合工具能够保证设计能知足每一个数字电路触发器对创建与保持时间的要求。然而,异步信号却给软件提出了难题。对新的时钟域来讲,从其它时钟域传来的信号是异步的。大多数综合工具在断定异步信号是否知足触发器时序要求时遇到了麻烦。由于它们不能肯定触发器处于非稳态的时间,因此它们也就不能肯定从一个触发同步

器经过组合逻辑到达下一个触发器的总延迟时间。因此,最好的办法是使用一些电路来减轻异步信号的影响。 class

信号同步:效率

信号同步的目的是防止新时钟域中第一级触发器的亚稳态信号对下级逻辑形成影响。简单的同步器由两个触发器串联而成,中间没有其它组合电路。这种设计能够保证后面的触发器得到前一个触发器输出时,前一个触发器已退出了亚稳态,而且输出已稳定。设计中要注意将两个触发器放得尽量近,以确保二者间有最小的时滞(clock skew)。 

IC 制造厂提供同步单元,帮助完成信号同步工做。这些单元一般包括一个有很是高增益的触发器,它比普通触发器耗电更高,也比较大。这种触发器下降了对输入信号创建-保持时间的要求,而且当输入信号致使亚稳态时,它能够防止出现振荡。另外一种同步器单元包括两个触发器,省去了将两个单独触发器靠近放置的工做,也防止设计人员误在两个触发器间加入任何其它的组合逻辑。为了使同步工做能正常进行,从某个时钟域传来的信号应先经过原时钟域上的一个触发器,而后不通过两个时钟域间的任何组合逻辑,直接进入同步器的第一个触发器中(图 1)。这一要求很是重要,由于同步器的第一级触发器对组合逻辑所产生的毛刺很是敏感。若是一个足够长的信号毛刺正好知足创建-保持时间的要求,则同步器的第一级触发器会将其放行,给新时钟域的后续逻辑送出一个虚假的信号。一个经同步后的信号在两个时钟沿之后就成为新时钟域中的有效信号。信号的延迟是新时钟域中的一到两个时钟周期。一种粗略的估算方法是同步器电路在新时钟域中形成两个时钟周期的延迟,设计者须要考虑同步延迟将对跨时钟域的信号时序形成的影响。

 

数据路径设计:

在进行信号同步时有一个重要的规则,那就是不该当在设计中的多个地方对同一信号进行同步,即单个信号扇出至多个同步器。由于同步要花一到两个时钟周期,设计者不能确切地预测到每一个信号什么时候跨越一个时钟域。此外,在新时钟域中一组经同步后的信号其时序是不定的,由于同步延迟能够是一到两个时钟周期,这与输入信号到达同步器的时间有关。这种状况会在各个同步信号间造成一种“竞争情况”。这种竞争情况在须要跨越时钟域传输的多组信号间也会发生,例如数据总线、地址总线和控制总线等。所以,不能对组中的每一个信号单独使用同步器,也不能对数据或地址总线的每一位单独使用同步器,由于在新的时钟域中,要求每一个信号同时有效。

 一种解决总线同步问题的方法是使用一个保持寄存器和握手信号。这种电路包括一个保持信号总线的寄存器,以及一个握手机制(图 7)。握手信号指示新时钟域的电路什么时候能够对总线采样,以及源电路什么时候能够更换当前寄存器中保存的内容。 

 

在这种设计中,传输电路将数据(信号总线)存储在保持寄存器,同时发出请求信号。这两个动做能够同时发生,由于请求信号至少要花一个时钟周期才能让接收电路检测到它(最小的握手-同步延迟)。当接收电路采样到数据(信号总线)时,它发出一个响应信号。这种设计使用了全握手方法,因此要花较长时间才能完成整个传输。对接收电路而言,使用全握手信号的设计有较大的时间窗口用于对信号总线采样,于是效率较低。如用部分握手方法代替全握手方法则能够加快传输速度。 

用这种总线同步方式,你能够同步握手信号,但不能同步信号总线。信号总线来自于保持寄存器,它在接收电路采样前一直保持稳定。注意,若是传输电路向接收电路提交数据太快以至来不及处理,则应用中的总线同步可能不起做用。 

 

 

高级数据路径设计:

    在许多状况下,数据在跨越时钟域时须要“堆积”起来,所以使用单个保持寄存器没法完成工做。例如一种状况是某个传输电路猝发式发送数据,接收电路来不及采样。另外一种状况是接收电路采样速度超出传输电路发送数据的速度,但采样的数据宽度不够。这些状况就要使用 FIFO 了。基本上,设计者使用 FIFO 有两个目的:速度匹配或数据宽度匹配。在速度匹配时,FIFO 较快的端口处理猝发的数据传输,而较慢的端口则维持恒定的数据流。可是,虽然访问方式和速度不一样,但进出 FIFO 的平均数据速率必须是相同的,不然 FIFO 就会出现上溢(overflow)或下溢(underflow)问题。与单寄存器设计相同,FIFO 将数据保存在寄存器或存储器中,同时同步状态信号,判断什么时候能够把数据写入 FIFO 或从 FIFO 中读出。 

    在速度匹配应用中,每一个端口(读或写)的时钟不一样。FIFO 中的寄存器使用写端口时钟,就像保持寄存器使用电路时钟来改变寄存器内容同样。信号同步发生在指针逻辑中,并且比握手信号要复杂得多。如今指针逻辑的设计有多种方法。第一种方法是将读、写选通进行同步,同时在各个时钟域使用计数器来跟踪 FIFO 中可用的项。计数器反映出可用于读写的 FIFO 项目号,计数器也与相应的端口同步。读计数器跟踪包含有效数据的项数,而写计数器则跟踪能够存储数据的项数。当对指针逻辑进行复位时,因为没有数据可读,读计数器从零起始。写计数器则从 FIFO 中项的总数开始计数,即全部项都可用来存储数据。 

    读选通讯号累减读计数器,并与写时钟域同步,由于它同时也累加写计数器。写选通讯号则累减写计数器,并与读时钟域同步,由于它同时也累加读计数器。这种设计须要单时钟宽度脉冲以及用于读、写选通的脉冲同步器,由于当一个电平信号从一个时钟域跨越到另外一个更快的时钟域时,在较快时钟域中它能在更多的时钟周期中保持有效。因为只要读或写信号是有效的,每一个计数器就会发生变化,所以较快的时钟域就检测到更多的读、写,超出较慢时钟域实际发生的数量。脉冲同步器能够将一个时钟域的时钟宽度脉冲转换为新时钟域的时钟宽度脉冲,每一个脉冲都表示一次 FIFO 的读或写。 

    这种 FIFO 状态技术对读、写状态都不太有利。当 FIFO 中全部项均充满时,写端口状态指示为满,并在读选通触发后继续指示 FIFO 满,由于同步过程会使选通讯号延迟送给写计数器。读端口为空时也会出现这种状况,由于同步过程会使写选通讯号延迟到达读计数器。

    这种设计的另外一种考虑是及时检测全满/全空状态。若是 FIFO 还有一项可用,而且有写选通触发,则 FIFO 必须当即置为全满状态。这样才能提早一个时钟给出全满标志,使 FIFO 有足够时间防止下一个数据写入而产生溢出。对 FIFO 的读端口也是这样。这种状况下,若是 FIFO 里只有一个数,而且有读选通触发,则必须置全空状态,以给读电路足够的时间防止读空 FIFO。 

    这种指针逻辑限制电路在每一个时钟周期中访问 FIFO,即便在慢速时钟域中也是这样。这一功能的优势在于访问 FIFO 的电路至少有一个时钟周期来评估 FIFO 的状态。FIFO 能够将全部项都填满数据,而不会出现数据被覆盖或全空无数据可读的状况。这种设计的另外一个优势是每一端均可以读其相应的计数器,来判断 FIFO 中还有多少项可用。设计者能够将这

种 FIFO设计用在进行屡次数据读/写的电路中,而不会形成上溢或下溢的状况。 

    这种设计的不足之处是由计数器来判断状态,而不是直接比较读、写指针。对大型 FIFO 来讲,这些计数器也很大。并且,因为使用脉冲同步时,来自较快时钟域的读、写脉冲在较慢时钟域的脉冲间至少必须有两个时钟周期,所以平均数据速率为最低时钟频率的一半。解决这些问题的一种方法是采用直接指针比较法。 

    在这种 FIFO 设计中,读、写指针的比较决定了 FIFO 的状态。异步设计中的指针比较更富有挑战性,由于每一个指针位于不一样的时钟域中,对信号总线的同步要求在同步握手信号期间总线不发生改变。将这种技术用于指针同步的 FIFO 设计可能会很慢。要解决这个问题,FIFO 指针逻辑使用了格雷码,代替指针使用的二进制码。 

    格雷码在每一次计数增减时只改变其中的一位(表 3)。你能够在格雷码总线上使用同步器,由于每一次总线改变时只有一根信号线有变化,因而就消除了格雷码总线各位经过不一样同步器时的竞争状况。这种设计的指针为格雷码计数器。使用二进制指针时须要将其变换成格雷码后的同步指针,而使用变换逻辑会违反对同步信号的限制,即同步的信号在跨越

时钟域前要来自触发器。 

    格雷码计数器是一个二进制累加器,在累加器前、后各带有一个转换器,分别用于格雷码转换为二进制码,和二进制码转换为格雷码(图 8)。格雷码与二进制码的转换是一个异或运算,因此只需比一个二进制计数器多几个逻辑电平。在格雷码转换成二进制码时,使用:BN=GNBN-1=BN+GN-1BN-2=BN-1+GN-2 ... B1=B2+G1B0=B1+G0。而将二进制码转换成格雷码时,使用:GN=BNGN-1=BN+BN-1GN-2=BN-1+BN-2 ... G1=B2+B1G0=B1+B0。在设计中能够采用一样的技术来比较格雷码指针的值,即在各个指针与二进制比较逻辑之间增长转换器。

    用这种指针逻辑的 FIFO 很快,每一个时钟周期中电路均可以读写 FIFO。可是,在每一个周期都访问 FIFO 意味着 FIFO 状态要包括“将满”和“将空”两种指示,这样读写 FIFO 的电路才能有中止时间。“将满”表示只能再写入一项,“将空”则表示只有一项可读。这种状况描述了一个要求最少的可能状态信号的设计,以及一个须要更多指示的设计,若是在固定的最小尺寸状况下用猝发方式访问 FIFO 的电路的话。 

    这种 FIFO 状态技术会给读、写带来不良状态。当 FIFO 满时,写端口的状态指示已满,而在电路从 FIFO 中读出一项后,该状态仍为满,由于同步机制使读指针相对写入一侧的比较逻辑有个延迟。一样,在读出一侧的空状态指示也有这个问题,由于同步机制使写指针相对读出一侧的比较逻辑有延迟。

    若是你在设计跨不一样时钟域电路时,使用一些技术来下降通讯失败的风险,则处理跨时钟域的信号就再也不是艰巨的任务。同步机制能够防止接收跨时钟域信号的触发器出现亚稳态,从而避免致使不可预知的电路行为。对于在多个时钟周期内一直保持有效的信号来讲,电平同步器的效果很好。对于要转换成新时钟域脉冲的较慢时钟域电平信号,要采用边沿检测同步器。最后,对跨时钟域的脉冲信号应使用脉冲同步器。还要记住,当一个信号总线跨越时钟域时,整个总线要在同一个时钟周期内到达新的时钟域。不要分别同步每个信号,而要采用一个保持寄存器和握手方式。握手用来表示寄存器中的信号什么时候有效,什么时候能够采样。对数据总线来讲,握手和一个保持寄存器颇有用,但每次向新时钟域传送的数据字不超过一个。 

 

 

 

 

    在最近作的一个USB2.0 Controller中,本人就使用了异步FIFO来解决跨时钟域信号。异步FIFO是在ISE中直接例化出来,很好的解决了速率匹配和数据宽度匹配问题。