翻译_Clock Domain Crossing Design
翻译_Clock Domain Crossing Design
原文标题及连接:Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog.
作者:Clifford E. Cummings
Sunburst Design, Inc.
cliffc@sunburst-design.com
摘要
在多时钟设计中,需要在时钟域交叉(Clock Domain Crossing,CDC)边界处仔细构造重要的设计考虑因素。本文详细介绍了一些最新的策略和众所周知的最佳方法,以解决跨CDC边界传递一个或多个信号的问题。
文中包括了与CDC验证相关的技术,以及一个有趣的2深FIFO设计,用于在时钟域之间传递多个控制信号。
尽管本文描述的设计方法通常可以使用任何硬件描述语言(HDL)实现,但示例使用的是高效的SystemVerilog技术。
1.0 引言
在2001年,我提交了我的第一篇关于多异步时钟设计的论文。那时,我没有找到任何好的资源来描述进行适当的多时钟设计所需的设计和综合技术。
2001年的论文是我多年ASIC和FPGA设计经验中收集的技术的集合。在2001年会议演讲结束时,数十位工程师和同事向我分享了足够多的有趣想法和技术,以至于我可以为这个主题写一个续集。在过去的八年里,我在高级和专家级的Verilog和SystemVerilog培训课程中包括了多时钟设计技术的指导,同时在这段时间里,更多的同事和学生与我分享了额外的有趣的多时钟设计技术。
自2001年发布第一篇多时钟论文以来,业界普遍将这些设计方法归类为时钟域交叉(CDC)技术。我将在本文中使用这个通用术语。
本文包括了2001年论文中描述的最佳技术,以及在过去十年中与我分享的更新的有趣和高效的多时钟设计技术的集合。实际的会议演讲幻灯片将主要是自2001年原始演讲以来纳入的新技术的集合,只保留足够的原始幻灯片来介绍基本的CDC设计概念和问题。
2.0 亚稳态
亚稳态指的是在设计的正常操作期间,信号在一段时间内不假定稳定的0或1状态。在多时钟设计中,亚稳态无法避免,但可以中和亚稳态的有害影响。
引用Dally和Poulton的书[9]中关于亚稳态的内容:
当用时钟采样一个变化的数据信号时…事件的顺序决定了结果。事件之间的时间差异越小,确定哪个事件先发生所需的时间就越长。当两个事件发生得非常接近时,决策过程可能需要的时间超过了分配的时间,这时就会发生同步失败。
图1显示了当一个在第一个时钟域产生的信号在第二个时钟域的时钟信号的上升沿太近时发生的同步失败。同步失败是由输出进入亚稳态并且在必须再次采样输出之前没有收敛到合法稳定状态引起的。
2.1 为什么亚稳态是个问题?
那么,为什么亚稳态是个问题呢?图2显示了一个在接收时钟域中穿越额外逻辑的亚稳态输出,可能会导致整个设计中传播非法信号值。由于CDC信号可能会在一段时间内波动,接收时钟域中的输入逻辑可能会识别波动信号的逻辑电平为不同的值,从而将错误的信号传播到接收时钟域。
每个在设计中使用的触发器都有一个指定的建立时间和保持时间,或者在上升时钟边沿之前和之后数据输入不允许变化的时间。这个时间窗口被精确地指定为设计参数,以防止数据信号在太靠近可能使输出进入亚稳态的另一个同步信号时发生变化。
3.0 同步器
在时钟域之间传递信号时,一个重要的问题是,我是否需要采样从一个时钟域传递到另一个时钟域的信号的每个值?
3.1 两种同步场景
在跨CDC边界传递信号时,有两种可能的场景,确定哪种场景适用于您的设计非常重要:
- 允许在时钟域之间传递的样本被错过。
- 必须采样传递至时钟域之间的每个信号。
**第一种场景:**有时不必采样每个值,但采样的值必须准确。一个例子是标准异步FIFO设计中使用的一组格雷码计数器。在正确设计的异步FIFO模型中,同步的格雷码计数器不需要捕获来自相反时钟域的每个合法值,但关键是采样的值必须准确,以识别何时发生了满和空条件。
**第二种场景:**CDC信号必须在CDC信号上发生变更之前被正确识别或确认。
在这两种场景中,CDC信号将需要某种形式的同步进入接收时钟域。
3.2 双触发器同步器
再次引用Dally和Poulton[9]关于同步器的话:
同步器是一个设备,它采样一个异步信号,并输出一个信号版本,该信号的转换与本地或采样时钟同步。
数字设计师使用最简单和最常见的同步器是双触发器同步器,如图3所示。
第一个触发器将异步输入信号采样到新的时钟域,并等待一个完整的时钟周期,以允许任何在第一阶段输出信号上的亚稳态衰减,然后第一阶段信号被相同的时钟采样到第二阶段触发器,预期的目标是,第二阶段信号现在是稳定且有效的信号,已同步并准备好在新的时钟域内分发。
3.3 MTBF - 故障前平均时间
对于大多数同步应用,计算任何穿过CDC边界的信号的故障前平均时间(MTBF)是很重要的。
在这里,故障意味着传递到同步触发器的信号,在第一阶段同步器触发器上变为亚稳态,并在下一个时钟周期后继续是亚稳态,当它被采样到第二阶段同步器触发器时。由于信号在经过一个时钟周期后没有稳定到已知值,信号在被采样并传递到接收时钟域时可能仍然是亚稳态,从而导致相应逻辑中的潜在故障。
当计算MTBF数字时,较大的数字优于较小的数字。较大的MTBF数字表示潜在故障之间的时间较长,而较小的MTBF数字表示亚稳态可能频繁发生,类似地在设计中引起故障。
Dally和Poulton[9]给出了一个非常好的方程式和非常彻底的分析,可以执行计算同步器电路的MTBF。不重复方程式和分析,应该指出,直接影响同步器电路MTBF的两个最重要因素是:
-
采样时钟频率(信号被采样进入接收时钟域的速度有多快);
-
数据变化频率(跨CDC边界的数据变化速度有多快)。
从上述部分方程式可以看出,在更高速度的设计中,或者当采样数据变化更频繁时,故障发生的频率更高(MTBF更短)。
3.4 三触发器同步器
对于一些非常高速度的设计,双触发器同步器的MTBF太短,增加了第三个触发器以增加MTBF到一个令人满意的时间段。当然,令人满意是由设计的架构师决定的。
3.5 从发送时钟域同步信号
**关于CDC设计的一个常见问题是:**在将信号传递到接收时钟域之前,是否有必要对来自发送时钟域的信号进行寄存?
这个问题中隐含的假设是,既然CDC信号将被同步到接收时钟域,因此它们在发送时钟域中不需要同步。这种理论是错误的,通常应该要求在发送时钟域中对信号进行寄存。
考虑一个示例,其中发送时钟域中的信号在被传递到接收时钟域之前没有进行寄存,如图6所示。
在这个示例中,来自发送时钟域的组合逻辑输出可能在CDC边界处经历组合逻辑稳定过程。
这种组合逻辑稳定实际上增加了数据变化频率,可能会产生短时间的数据振荡,从而增加了在变化时被采样的边缘数量,相应地增加了采样变化数据并产生亚稳态信号的可能性。
3.6 同步信号到接收时钟域
应该在发送时钟域中同步信号,然后再将其传递到CDC边界。
从发送时钟域同步信号可以减少在接收时钟域中可能采样的边缘数量,有效地降低了MTBF方程中的数据变化频率,从而增加了计算出的故障时间(见第3.3节,了解数据变化频率对MTBF的影响)。
在图7中,aclk逻辑在传递到bclk域之前在adat触发器上稳定并设置。adat触发器过滤了触发器输入上的组合逻辑稳定(a),并向bclk逻辑传递了一个干净的信号。
4.0 将快速信号同步到慢速时钟域
如第3.1节所讨论的,如果允许在时钟域之间传递的CDC信号被跳过,则在考虑信号宽度或同步技术时,它们在时钟域之间传递时的重要性就显现出来了。
与同步器相关联的一个问题是,来自发送时钟域的信号可能在被采样之前改变两次值,或者可能太接近慢速时钟域的采样边沿。每当信号从一个时钟域发送到另一个时钟域时,都必须考虑这种可能性,并且必须确定是否遗漏信号对于所讨论的设计来说是否是一个问题。
当不允许遗漏采样时,有两个通用的解决问题的方法:
- 开环解决方案,确保信号被捕捉而无需确认。
- 闭环解决方案,需要确认接收到跨越CDC边界的信号。
本节讨论了这两种解决方案。
4.1 在时钟域之间可靠传递信号的要求
同步较慢的控制信号到较快的时钟域通常不是问题,如果较快的时钟域的频率至少是较慢时钟域的1.5倍,因为较快的时钟信号将至少一次或多次采样较慢的CDC信号。
设计者可能会利用这一事实,通过使用简单的双触发器同步器在时钟域之间传递单个CDC信号。
认识到在较快的时钟域中采样较慢信号比在较慢的时钟域中采样较快信号潜在的问题要少,这有助于简化设计。
4.1.1 “三边沿”要求
Mark Litterick[4]指出,当通过双触发器同步器在时钟域之间传递一个CDC信号时,CDC信号必须比接收域时钟周期的宽度长1.5倍。
Litterick将此要求描述为输入数据值必须在三个目标时钟边沿上保持稳定。
对于源时钟和目的时钟频率异常长的情况,这一要求可能可以安全地放宽到接收时钟域周期时间的1/4倍或更短,但“三边沿”准则是最安全的初始设计条件。相比于在仿真期间动态测量CDC信号的部分宽度,使用SystemVerilog断言来证明这一点更为容易和可靠。
“三边沿”要求实际上适用于开放环和闭环解决方案,但实现闭环解决方案自动确保至少三个边沿被检测到所有CDC信号。
4.2 问题-传递一个快速CDC脉冲
考虑一个严重的问题情况,即发送时钟域的频率高于接收时钟域,且一个CDC脉冲在发送时钟域中只持续一个周期。
如果CDC信号仅在一个快速时钟周期内被激活,那么这个信号可能在慢速时钟的两个上升沿之间变化,从而没有被慢速时钟域捕获,如图8所示。
4.3 问题-采样一个不够长的长CDC脉冲-但是依然不够长
考虑一个有些违反直觉的情况,即发送时钟域向接收时钟域发送一个脉冲,这个脉冲宽度略宽于接收时钟的周期。
在大多数情况下,信号将被采样并通过,但存在一个小但真实的可能性,即CDC脉冲变化得太接近接收时钟域的两个上升时钟边沿,从而违反了第一个时钟边沿的建立时间,并违反了第二个时钟边沿的保持时间,没有形成预期的脉冲。
这种可能的故障情况如图9所示。
4.4 开环解决方案-使用同步器采样信号
解决这个问题的一个潜在方法是断言CDC信号一段时间,这个时间超过了采样时钟的周期时间。如第4.1.1节所讨论的,最小脉冲宽度是接收时钟频率周期的1.5倍。假设CDC信号至少被采样一次,可能被采样两次。
开环采样可以用于相对时钟频率固定并且正确分析的情况。
优点:开环解决方案是在不需要确认接收信号的情况下,跨CDC边界传递信号的最快方式。
缺点:与开环解决方案相关的最大潜在问题是,另一位工程师可能会错误地将解决方案视为通用解决方案,或者设计要求可能会更改,而工程师可能没有重新分析原始的开环解决方案。通过在模型中添加SystemVerilog断言来检测输入脉冲是否从未超过“三边沿”设计要求,可以最小化这个问题。
4.5 闭环解决方案-使用同步器采样信号
解决这个问题的第二个潜在方法是发送一个启用控制信号,将其同步到新的时钟域,然后通过另一个同步器将同步信号作为确认信号传回发送时钟域。
优点:同步一个反馈信号是非常安全的技术,用于确认第一个控制信号已经被识别并采样到新的时钟域。
缺点:与同步控制信号在两个方向上的潜在显著延迟有关,然后才允许控制信号更改。
5.0 在时钟域之间传递多个信号
在时钟域之间传递多个信号时,简单的同步器不能保证数据的安全传递。
工程师在处理多时钟设计时经常犯的一个错误是,在同一个事务中传递需要跨越不同时钟域的多个CDC位,并且忽视了对CDC位进行同步采样的重要性。
问题是,同步到一个时钟的多个信号会经历微小的数据变化偏差,这些偏差有时可能在第二个时钟域的不同上升时钟边沿上被采样。即使我们能够完全控制并匹配多个信号的走线长度,上升和下降时间的差异以及芯片上不同区域的处理变化可能会引入足够的偏差,导致在本应仔细匹配的走线上发生采样失败。
必须采用多位CDC策略,以避免多位值的偏斜采样。
5.1 多比特CDC策略
为了避免多比特值的偏斜采样,我将多比特CDC策略分为三个主要类别:
- 多比特信号整合:在可能的情况下,尝试将多个CDC位合并为1位CDC信号。这可以减少由于多位信号间的微小偏差而导致的采样错误。
- 多周期路径(MCP)公式:使用同步加载信号来安全地传递多个CDC位。这种方法通过确保数据在接收时钟域中稳定,直到同步的控制信号允许采样,从而避免了偏斜采样。
- 使用格雷码:格雷码是一种计数方式,其中只有一个位在任何给定时间变化,这使得它们非常适合在多时钟设计中同步传递,因为它们减少了在接收时钟域中采样时发生错误的风险。
这些策略的详细描述和实现方法将在本文的后续部分中介绍。
5.2 多比特信号整合
在可能的情况下,尝试将多个CDC信号整合到一个1位CDC信号中。问问自己,我真的需要多个位来控制跨越CDC边界的逻辑吗?
简单地对所有CDC位使用同步器并不总是足够的,如下例所示。
如果控制信号的顺序或对齐很重要,必须注意正确地将信号传递到新的时钟域。本节中展示的所有示例都过于简化,但它们紧密模仿了实际设计中经常出现的情况。
5.3 问题-两个同事需要的控制信号
在图12所示的简单示例中,接收时钟域中的一个寄存器需要同时接收到加载信号和使能信号才能将数据值加载到寄存器中。
如果加载信号和使能信号在同一发送时钟边沿上被驱动,那么控制信号之间可能存在的小的偏斜可能导致这两个信号在接收时钟域内被同步到不同的时钟周期中。在这些条件下,数据将无法被加载到寄存器中。
5.3.1 解决方案-整合
第5.3节中提到的问题解决方案很简单,就是整合控制信号。
如图13所示,在接收时钟域中,将加载和使能寄存器输入信号仅由一个加载-使能信号来驱动。整合可以消除两个控制信号在时间上错位到达的可能性。
5.4 问题-两个相位偏移的时序控制信号
图14展示了两个使能信号,aen1和aen2,它们是按顺序从发送时钟域驱动到接收时钟域,以控制流水线数据寄存器的使能输入。
问题在于,在第一个时钟域中,aen1控制信号可能在aen2控制信号生成之前稍微终止,接收时钟的上升沿可能发生在aen1和aen2控制信号脉冲之间的微小间隙中,导致在接收时钟域的使能控制信号链中形成一周期的间隙。这将导致第二个寄存器错过a2数据值。
5.4.1 解决方案-整合一个额外的触发器
解决这个问题的方法,如图15所示,是只向接收时钟域发送一个控制信号,并在接收时钟域内生成第二个相位偏移的流水线使能信号。
5.5 问题-多个CDC信号
图16展示了两个编码的控制信号在时钟域之间传递。如果这两个编码信号在采样时有轻微的偏斜,接收时钟域内可能在一个时钟周期内产生错误的解码输出。
5.5.1 传递多个CDC信号的解决方案
可以使用多周期路径(MCP)公式或FIFO技术来解决与传递多个CDC信号相关的问题。MCP公式的定义和描述从第5.6节开始。
至少有两种MCP公式可以用来解决这个问题:
- 带反馈的闭环MCP公式。
- 带确认反馈的闭环MCP公式。
MCP公式的实现技术从下一节开始描述。
还有至少两种FIFO策略作为这个问题的闭环解决方案:
- 异步FIFO实现。
- 2深FIFO实现。
FIFO实现技术从5.8节开始描述。
5.6 多周期路径(MCP)公式
使用多周期路径(MCP)公式是一种常用技术,用于安全地在时钟域之间传递多个CDC信号。
MCP公式指的是将未同步的数据发送到接收时钟域,并与同步的控制信号配对。数据和控制信号同时发送,允许数据在目的地寄存器的输入上建立,而控制信号在到达目的地寄存器的加载输入之前,需要经过两个接收时钟周期的同步。
优点:
- 发送时钟域不需要计算在时钟域之间发送的适当脉冲宽度。
- 发送时钟域只需要将一个使能信号切换到接收时钟域,以表示数据已经传递并准备加载。使能信号不需要返回到初始逻辑电平。
这种策略在不同步的情况下传递多个CDC信号,并同时传递一个同步的使能信号到接收时钟域。接收时钟域在同步使能信号通过同步并到达接收寄存器之前,不允许采样多比特CDC信号。
这种策略被称为多周期路径(MCP)公式[8],因为未同步的数据字直接传递到接收时钟域,并保持多个接收时钟周期,允许使能信号在允许未同步数据字改变之前被同步并被接收时钟域识别。
由于未同步的数据在被采样前被传递并保持稳定多个时钟周期,所以不存在采样值会变为亚稳态的危险。
5.6.1 使用同步使能脉冲的MCP公式
也许在时钟域之间传递同步使能信号的最常见方法是使用一个切换型使能信号,该信号被传递给同步脉冲发生器,以指示未同步的多周期数据字可以在下一个接收时钟边上被捕获,如图18所示。
同步使能脉冲生成的关键特性是输入信号的极性无关紧要。在图18中:
- d输入在第1个周期内被切换高,在第4个周期内一个高信号已经通过三个同步触发器传播。
- 在第3个周期内,q2和q3触发器的输出具有不同的极性,导致同步使能脉冲在同一周期内在异或门的输出上形成。
- 同样,d输入在第7个周期内被切换低,到第10个周期内一个高信号已经通过三个同步触发器传播。
- 再次,在第9个周期内,q2和q3触发器的输出具有不同的极性,导致同步使能脉冲在异或门的输出上形成。
由于所有在第5.0节中描述的MCP公式都使用同步使能脉冲生成电路,因此创建并使用一个更小的等效符号来表示同步使能脉冲生成电路是有用的。等效符号显示在图19中。
除了从任何d输入极性生成脉冲外,同步使能脉冲生成电路还有一个q输出,它跟随d输入,延迟三个时钟周期。q输出通常用作反馈信号,并通过发送时钟域中的另一个同步使能脉冲生成电路作为确认信号传递。
图20展示了一个典型的发送-接收切换脉冲生成设计。
使用此技术,需要接收时钟域在检测到脉冲时就位以捕获数据,因为脉冲每个多周期数据字仅对一个接收时钟周期有效。
5.6.2 闭环-使用反馈的MCP公式
使用MCP公式的一个重要技术是将使能信号作为确认信号传回发送时钟域,如图21所示。
在图21的示例中,确认反馈信号(b_ack)生成一个确认脉冲(aack),该脉冲用作小型READY-BUSY,1状态FSM(有限状态机)的输入,该FSM生成一个就绪信号(aready),以指示现在可以安全地更改数据输入(adatain)的值了。
一旦aready信号变高,发送方就可以发送新的数据(adatain)和伴随的asend控制信号。
这是一个自动反馈路径,它假定接收时钟域始终准备好通过MCP公式同步接收下一个数据字。
5.6.3 闭环-使用确认反馈的MCP公式
完全响应式技术的变体,使用MCP公式,是在接收时钟域确认接收到数据后,通过bload脉冲,才将使能信号作为确认信号传回发送时钟域,如图22所示。
在图22的示例中,接收时钟域有一个小型WAIT-READY,1状态FSM,当数据在数据寄存器的输入上有效时,它向接收逻辑发送一个有效信号(bvalid)。
数据实际上在接收逻辑确认应该加载数据时才会被加载,通过断言bload信号来实现。
在数据被加载之前,不会向发送时钟域发送反馈,然后b_ack信号就像具有自动反馈的MCP公式一样被发送回来。
这是一个需要接收时钟域采取行动才能在数据被捕获并发送反馈之前的反馈路径。
5.7 同步计数器
如前所述,当在时钟域之间传递多个信号时,一个重要的问题是,我是否需要采样从一时刻钟域传递到另一时刻钟域的信号的每个值?对于计数器来说,答案通常是否定的!
参考文献[1]详细介绍了FIFO设计技术,其中在时钟域之间采样了格雷码计数器,并且经常错过了中间的格雷计数值。对于这种FIFO设计,更大的考虑是确保计数器不会超出其边界,这可能会导致错过满和空标志的检测。即使在时钟域之间采样的格雷计数值经常错过,设计也是健壮的,并且所有重要的格雷计数值都被适当地采样。详见[1]。
既然一个有效的设计可能被允许跳过一些计数值样本,那么是否可以使用任何计数器来在CDC边界上传递计数值?答案是否定的。
5.7.1 二进制计数器
二进制计数器的一个特点是,在所有顺序二进制递增操作中,有一半需要在同一时刻变化两个或更多的计数器位。
尝试在CDC边界上同步二进制计数器就像尝试在时钟域之间同步多个变化的CDC位一样。
如果一个简单的4位二进制计数器从地址7(二进制0111)变化到地址8(二进制1000),所有四个计数器位将同时变化。
如果在这种转换中间出现同步时钟边沿,可能在接收时钟域内采样并同步任何4位二进制模式,如图23所示。
在FIFO设计中,新同步的二进制值可能会错误地触发满或空标志,或者更糟糕的是,可能没有触发实际的满或空标志,导致数据因FIFO溢出而丢失,或者在FIFO实际上为空时尝试读取数据,导致读取到无效数据。
5.7.2 格雷码
格雷码以Frank Gray[4]命名,是多时钟设计中最安全的计数器类型。格雷码只允许每个时钟转换时改变一个位,从而消除了尝试在时钟域之间同步多个变化的CDC位的问题。
标准格雷码具有非常好的转换属性,可以简单地转换为二进制码并反向转换。利用这些转换属性,可以设计出高效的格雷码计数器。
5.7.3 格雷码到二进制的转换
要将格雷码值转换为等效的二进制码值,以n位格雷码值为例,二进制位0等于格雷码位0与从1到n的所有其他格雷码位的异或结果。二进制位1等于格雷码位1与从2到n的所有其他格雷码位的异或结果,以此类推。最高位二进制位就是最高位格雷码位。
一个4位格雷码到二进制的转换方程示例如图24所示。
格雷码到二进制转换的最简单编码方式是编写一个for循环,并在格雷码向量上执行可变索引范围的异或归约操作,每次循环时LSB的索引范围增加,直到最后简化为对格雷码向量最高位的简单赋值,即bin[MSB] = ^gray[MSB:MSB](只是格雷码向量的1位MSB),如示例1所示。
不幸的是,Verilog和SystemVerilog不允许使用变量索引范围进行部分选择,因此示例1中的代码虽然概念上正确,但无法编译。
要解决这个问题,要记住异或门实际上是一个可编程的非门。如果一个输入被连接到高电平,另一个输入将被反转并传递到输出。同样,如果一个输入被连接到低电平,另一个输入将被传递到输出,而不会反转(从输入到输出没有变化)。
利用任何涉及0输入的额外异或操作都不会改变操作结果的事实,格雷码到二进制转换的方法是对重要的格雷码位与填充的0进行异或,如图25所示。
对应的参数化SystemVerilog模型例2所示。这个示例在语法上是正确的,可以编译并工作。
所有与0输入的额外异或操作会发生什么?综合工具会识别出在异或门的一个输入上有一个常数0,可以优化掉,以推断出非常高效的设计实现。
5.7.4
将二进制值转换为等效的格雷码值,以n位二进制值为例,格雷码位0等于二进制位0和位1的异或结果。格雷码位1等于二进制位1和位2的异或结果,以此类推。最高位格雷码位就是最高位二进制位。
一个4位二进制到格雷码的转换方程示例如图26所示。
编码一个二进制到格雷码的转换器最简单的方法是编写一个连续赋值,该赋值执行二进制向量与其右移版本的位异或操作,如示例3所示。此示例在语法上是正确的,可以编译并工作。
5.7.5 格雷码计数器风格 #1
我们可以使用5.7.3节和5.7.4节中展示的转换来构建一个格雷码计数器。对于任何格雷码计数器,重要的是要记住格雷码输出必须被寄存,以消除设计中的任何组合逻辑稳定问题。
格雷码计数器风格 #1 的 SystemVerilog 代码结合了一个格雷码到二进制的转换器、一个二进制到格雷码的转换器,并在转换之间递增二进制值,如图27所示。
对应的参数化 SystemVerilog 模型为格雷码计数器风格 #1 展示在示例4中。
5.7.6 格雷码计数器风格 #2
我们可以通过仅使用5.7.4节中展示的二进制到格雷码的转换来构建第二种风格的格雷码计数器。这种格雷码计数器实际上既包含一个二进制计数寄存器也包含一个格雷码计数寄存器。
SystemVerilog代码为格雷码计数器风格 #2,结合了一个二进制计数器,以消除对格雷码到二进制转换的需求,并使用下一个二进制计数值进行二进制到格雷码的转换,然后将其寄存到格雷码寄存器中。这种风格使用了两倍数量的触发器,但是生成下一个格雷码值的组合逻辑路径更短,这使得这种实现比格雷码计数器风格 #1更快。格雷码计数器风格 #2的块图展示在图28中。
对应的参数化SystemVerilog模型为格雷码计数器风格 #2,展示在示例5中。
5.8 额外的多比特CDC技术
除了在早期部分描述的MCP公式技术外,我发现许多工程师使用标准FIFO(先进先出队列)来在时钟域之间传递数据和控制信号。
至少有两种有趣的FIFO实现策略可以用来解决多比特CDC信号完整性问题:
- 异步FIFO实现。
- 2深FIFO实现。
5.8.1 使用异步FIFO进行多比特CDC信号传递
传递多个位,无论是数据位还是控制位,都可以通过异步FIFO来完成。异步FIFO是一个共享内存或寄存器缓冲区,数据从写入时钟域插入,从读取时钟域移除。由于发送方和接收方都在它们各自的时钟域内操作,使用双端口缓冲区,如FIFO,是在时钟域之间安全传递多比特值的可靠方式。
标准的异步FIFO设备允许只要FIFO未满,就可以插入多个数据或控制字,接收方可以在方便时提取多个数据或控制字,只要FIFO不为空。
大多数FIFO设计中的辛勤工作都是通过同步格雷码计数器来完成的,一种经过验证的FIFO设计技术在[1]中描述。
5.8.2 使用1深2寄存器FIFO同步器进行多比特CDC信号传递
另一种有趣的变体,用于在CDC边界传递多个控制和数据位,是使用1深两寄存器FIFO,如图29所示。
这个1深2寄存器FIFO具有一些有趣的特性。由于FIFO是仅使用两个寄存器或2深双端口RAM构建的,用于检测满和空的格雷码计数器是简单的翻转触发器,这实际上不过是1位二进制计数器(记住,标准格雷码的MSB与二进制码的MSB相同)。
在复位后,两个指针都被清除,FIFO为空,因此FIFO未满。我们使用非满条件的反转来表示FIFO准备好接收数据或控制字(wrdy为高)。在FIFO中写入数据或控制字后(使用wput),wptr翻转,FIFO变为满,或者说,wrdy信号变为低,这也禁用了翻转wptr的能力,因此也禁用了将另一个字放入2寄存器FIFO的能力,直到第一个字被接收时钟域逻辑移除。
这种设计中特别有趣的是,wptr现在指向2寄存器FIFO的第二个位置,所以当FIFO再次准备好(当wrdy为高)时,wptr已经指向下一个要写入的位置。
相同的概念在FIFO的接收端被复制。当一个数据或控制字被写入FIFO时,FIFO变为非空。我们使用非空条件的反转来表示FIFO有一个数据或控制字准备好被接收(rrdy为高)。
通过使用两个寄存器来存储多比特CDC值,我们能够从发送MCP公式中移除一个时钟周期,从确认反馈路径中再移除一个周期。
6.0 命名约定和设计分割
命名约定有助于确保良好的团队沟通,也促进了使用脚本语言来收集和分组设计中与特定时钟相关的所有信号。良好的设计分割可以显著减少多时钟设计的合成和验证工作量。本节讨论了推荐的命名约定和设计分割。
有两种方法可以解决潜在的CDC问题:
- 验证设计是否符合合格的CDC规则,
- 避免问题。
两种方法都很有价值,应该用来确保无差错的设计。
第一种方法,CDC设计规则的验证,通常需要使用特殊工具来检查设计中可能的CDC违规。当我在2001年撰写第一篇关于多时钟设计的论文时,我不知道市场上有任何工具执行CDC规则的检查。今天有许多公司提供这样的工具(见[11],了解CDC验证领域的公司和工具列表)。
第二种方法,避免问题,可以通过采用一些良好的编码准则来实现,如下所述。
6.1 时钟和信号命名约定
多个设计团队已经使用了几种有用的时钟和信号命名约定。
指导原则:对设计中的每个信号使用时钟命名约定来标识其时钟源。
理由:命名约定帮助所有团队成员识别设计中每个信号的时钟域,也使使用正则表达式“通配符”在综合脚本中对信号进行分组以进行时序分析变得更加容易。
一个经过验证的命名约定要求使用前缀字符来标识设计中的各种异步时钟域。包括的示例有:uClk用于微处理器时钟,vClk用于视频时钟,dClk用于显示时钟。
然后,每个信号都被同步到设计中的一个时钟域,并且每个信号名称都被标记有前缀字符,以标识用于生成该信号的时钟域。例如,任何由uClk生成的信号都被标记为u前缀在信号名称中,如uaddr、udata、uwrite等。任何由vClk生成的信号也被类似地在信号名称中标记为v前缀,如vdata、vhsync、vframe等。设计中其他时钟生成的所有信号都使用相同的信号命名约定。
使用此技术,设计团队中的任何工程师都可以轻松识别设计中任何信号的时钟域来源,并直接使用信号或通过适当的同步,以便信号可以在新的时钟域内使用。
确切的命名约定并不重要,但每个项目团队成员都同意遵守所选的命名约定至关重要。命名约定将显著提高设计团队的生产力。
6.1.1 没有命名约定的多时钟/多源模块
如果您的团队不使用任何特定的时钟导向信号命名约定,并且如果模块被允许具有多个时钟输入,那么CDC分析工具可能没有正确设置的危险,很容易错过不良的CDC设计实践。
即使您的团队可以使用良好的CDC分析工具,我强烈建议您采取几个简单的步骤,使分析和识别潜在CDC设计问题更容易识别和调试。
6.2 每个时钟域的时序验证
要验证任何设计,必须验证设计中每个时钟域的时序是否满足要求。尽管过去十年中工具已经改进,以帮助自动化分析和验证不同时钟域中的信号,但使用良好的分割和命名约定来处理多时钟设计仍然是一个好习惯。
通过将设计分割为只允许每个模块一个时钟,静态时序分析变得更加容易。
6.3 时钟导向的设计分割
一些最简单和最好的设计分割方法使用时钟边界进行设计分割。
指导原则:每个模块只允许一个时钟。
理由:静态时序分析和创建综合脚本更容易完成,如果是在单时钟模块或单时钟模块组上进行。
例外:连接所有不同时钟域信号的顶级模块自然会拥有所有时钟作为此模块的输入。为了最小化您的多时钟验证工作量,请只允许顶级模块具有多个时钟输入。
指导原则:将设计块分割成单时钟模块。
理由:使用STA(静态时序分析)工具可以很容易地验证完全同步的子块的时序,将设计块分割成多个单时钟域子块,将大型复杂的时序分析任务转变为多个完全同步的单时钟设计。
指导原则:创建同步器模块以将信号从一个时钟域传递到另一个时钟域,并只允许同步器模块中的每个模块有一个时钟。
理由:众所周知,任何从一个时钟域传递到另一个时钟域的信号最终都会遇到设置和保持时间问题。将CDC边界逻辑隔离开来,可以显著减少多时钟设计的设计与验证工作量。
在大多数情况下,同步器模块将是设计中唯一会有意设置和保持时间违规的模块。当在异步时钟域之间传递信号时,已知会发生时序违规,这就是为什么需要在设计中添加同步器。
考虑一个具有三个时钟域的设计示例,标记为aClk、bClk和cClk,如图30所示。在这个设计中,所有的aClk设计块被分组到一个单独的aClk逻辑块中。所有的bClk设计块被分组到一个单独的bClk逻辑块中,同样我们也创建了一个cClk逻辑块。任何起源于异步时钟域的信号在被允许驱动另一个逻辑块的输入之前,都必须通过同步器模块。
6.3.1 时钟分割模块的时序分析
使用时钟导向的设计分割策略,每个设计块的所有输入和输出都完全同步到仅有的一个时钟。这是使用STA工具进行验证的最容易类型,因为设计中没有错误路径。
将所有设计模块分组在每个时钟域内。设计中应该为每个时钟域形成一个组。这些组将作为独立的、完全同步的设计进行时序验证。对于每个时钟域,我们有一个单独的设计块,我们可以轻松地执行最坏情况(最大时间/设置时间检查)时序分析和最佳情况(最小时间/保持时间检查)时序分析。
同时使用这种时钟导向的分割策略,每个CDC边界已经被隔离在同步器模块中。每个同步器模块只包括ASIC或FPGA供应商提供(首选)的同步器单元,或者是使用触发器对连接形成的同步器等效单元。
如果同步器单元由ASIC或FPGA供应商提供,并且已经实例化到设计中,那么就不需要验证这些模块上的设置和保持时间,因为供应商应该已经创建了一个不会违反设置或保持时间的单元布局。
如果同步器是从RTL代码综合出来的,那么最重要的是执行最佳情况时序分析,以确保触发器没有被放置得太近,以至于第一个阶段的输出变化太快,无法满足第二阶段输入的保持时间要求。一位同事最近指出,也应该执行最坏情况时序分析,以防布局工具碰巧将两个同步器触发器放置在ASIC或FPGA芯片上的相距很远的地方。我同意这个更新的建议。
由于同步器块的设计和分割,允许每个模块只有一个时钟,静态时序分析变得更加容易。用于解决多时钟域问题的合成脚本命令现在成为分组、识别错误路径和执行最小-最大时序分析的问题。
6.4 使用MCP公式分割
虽然大多数时间,将设计按时钟边界分割成不同的设计块和同步器块是有效的,但如果需要使用MCP(多周期路径)公式在时钟域之间传递多个信号,那么一些传递到设计块的信号可能来自不同的时钟域,如图6.4所示。
即使具有异步输入的设计块仍然可以很容易地进行时序,如果设计中使用了基于时钟的命名约定。在对特定设计块执行STA(静态时序分析)之前,简单地从分析中排除异步输入。
通常,只有同步器的输入和MCP公式数据路径的输入需要"set_false_path"命令。如果使用了基于时钟前缀的命名方案,那么可以使用通配符轻松识别所有异步输入。在图31中,为了在bClk逻辑块内排除adata总线的STA,首先执行以下命令:
set_false_path -from { a* }
此命令应该足以从bClk STA中排除所有异步输入。
7.0 多时钟门级仿真问题
数字仿真模型通常会在同步器检测到跨时钟域信号的建立和保持时间违规时输出X值(未知值)。这经常导致门级仿真失败。那么,有哪些技术可以用来解决这个问题呢?
如第6.3.1节所述,当信号通过同步器跨越时钟域时,会经历建立和保持时间违规。这就是为什么需要在设计中加入同步器,以滤除那些变化太接近接收时钟域的时钟信号上升沿而可能产生亚稳态的信号。
7.1 同步器门级CDC仿真问题
在对多时钟设计的门级仿真中,ASIC库中的触发器模型会根据实际触发器的时序规格进行建模,并包含建立和保持时间表达式。ASIC库通常将触发器模型设计为在发生时序违规时在触发器输出上输出X值。
当仿真门级同步器时,建立和保持时间违规可能使ASIC库发出建立和保持时间错误消息,违规信号经常被驱动为X值。
这些X值传播到设计的其余部分,在尝试验证整个门级设计的功能性时会引起问题,如图31所示。
7.2 从门级仿真中去除X传播的策略
在过去10年中,多位尊敬的同事与我分享了解决信号在同步器的第一阶段违反建立或保持时间时产生X传播问题的多种策略。几乎所有解决这个问题的方法都涉及将建立和保持时间设置为0,这样就不会有建立或保持时间违规,因此也不会有X传播。
一些方法是不可取的,而其他一些方法是可取的。以下是一些被考虑用来解决X传播问题的策略。
7.2.1 模拟器命令关闭时序检查
大多数SystemVerilog仿真器都有一个命令选项可以忽略所有的时序检查,但这也会忽略设计其余部分所需的时序检查。
7.2.2 将触发器的建立和保持时间更改为0
可以将同步器中使用的任何ASIC库触发器的建立和保持时间设置为零,但这会导致该类型触发器的所有实例的建立和保持时间检查都被设置为零,包括可能想要用来测试设计的其余部分的触发器。
7.2.3 复制和修改新的触发器模型
可以复制ASIC库中的触发器,并将它们存储在具有不同名称的新SystemVerilog库中,将所有建立和保持时间设置为零,然后修改设计门级网表,用没有时序检查的修改后的库触发器替换所有第一阶段同步器ASIC库触发器,但这可能是一个容易出错且繁琐的过程,可能需要每次生成新网表时重复,或者可能需要创建一个makefile和脚本,以便每次生成新网表时自动进行修改。
7.2.4 Synopsys set_annotated_check命令
由Bhatnagar[5]建议的一种有用的方法是使用Synopsys命令修改设计中第一阶段触发器单元的SDF反向注释的建立和保持时间。Bhatnagar指出,SDF文件是基于实例的,因此更容易针对违规单元进行建立和保持时间的目标设定。Bhatnagar指出:
不要手动从SDF文件中删除建立和保持时间结构,更好的方法是在SDF文件中将现有建立和保持时间数字替换为零,仅针对违规的触发器。
Bhatnagar进一步指出,建立保持时间为零意味着不可能有时序违规,因此不会向设计其余部分传播未知数。Bhatnagar给出的以下dc_shell-t命令用于将建立和保持时间设置为零:
set_annotated_check 0 -setup -hold -from REG1/CLK -to REG1/D
使用创造性的命名约定,可以简化使用非常少的dc_shell-t命令将第一阶段触发器的SDF建立和保持时间全部反向注释为零的过程。
这项技术适用于使用Synopsys DesignCompiler工具的设计,但非Synopsys流程呢?
7.3 去除门级仿真中X传播的附加策略
所有在第7.2节至7.2.4节中描述的策略都是我在2001年第一次多时钟设计论文中分享的。在最初的演讲之后,至少有三家公司的工程师在演讲后走上前来分享去除门级仿真中X传播的类似技术描述。
从那时起,许多公司的其他工程师分享了更多的技术。这些技术在本节中描述,我对每年继续与我分享有趣技术的工程师们表示感激。向你们所有人致敬!
7.3.1 使用多个SDF文件
记住,去除不需要的X传播的关键是通过强制同步器输入的建立和保持时间为0,从而消除同步器输入上可能发生的所有建立和保持时间违规。
许多工程师告诉我,他们实际上生成了两个SDF文件。
第一个SDF文件包含了整个设计的所有实际延迟,包括准确的建立和保持时间。
然后工程师生成了第二个SDF文件,其中只包括了第一阶段触发器。在此文件中,建立和保持时间被设置为0。一些工程师手工构建此文件,其他人使用脚本生成此文件。
工程师随后使用$sdf_annotate
命令读取第一个SDF文件。然后他们读取第二个SDF文件,该文件覆盖了第一阶段同步器的数据输入的建立和保持时间。当使用两个SDF文件时,最后一个SDF文件对于每个实例都是有效的。所有时序都被准确注释,然后修改了第一阶段同步器的时序检查。
这种技术的优点是它可以用于使用所有工具的所有设计,而不仅仅是Synopsys ASIC设计。这是一种高度推荐的技术。
7.3.2 供应商同步器单元与支持SDF生成工具
其他工程师描述了一种解决X传播问题的好方法,但这种方法需要(a)对单元库的控制,或(b)与ASIC供应商的良好工作关系。
这种技术需要创建一个单独的同步器单元,并在两个触发器阶段之间建立适当的放置关系。要使这种方法奏效,供应商必须提供:
- 实际的同步器单元 - 这些将被实例化到设计中。
- 用于模拟同步器单元的SystemVerilog模型。
- 将同步器单元的建立和保持时间生成SDF文件的工具。
如果供应商可以提供这种单元和这些功能,那么只需要生成一个SDF文件,其中包含同步器单元的正确时序检查。
如果任何ASIC或FPGA供应商提供这种能力,他们将为他们的客户端基础提供巨大的帮助。我听说一些ASIC供应商提供这种能力。我不知道有任何FPGA供应商提供这种能力,但具有前瞻性的FPGA供应商将为他们的高级多时钟设计客户提供这种单元。
7.3.3 内置同步器支持的供应商
如果有人知道提供这种支持的供应商,请告诉我供应商是谁,提供适当的联系信息,我将定期更新本文,以表彰为设计社区提供这种能力的供应商。
供应商列表:(截至本文发布时,未列出任何供应商)
7.4 多时钟门级跨时钟域仿真的多个SDF文件
在我的第一次多时钟演讲后,至少有三家不同公司的工程师在演讲后走上前来分享解决门级仿真中X传播问题的类似技术。
技术涉及编写完整的SDF时序文件,然后要么手动要么使用脚本,为所有同步器模块的第一阶段触发器生成第二个SDF文件。第二个SDF文件将所有建立和保持时间设置为0,然后使用$sdf_annotate
命令将两个SDF文件应用于设计。第一个SDF文件将所有实际时序注释到整个设计,然后第二个SDF文件被读取以覆盖第一阶段同步器的建立和保持时间。
这种技术的优点是它可以用于使用所有工具的所有设计,而不仅仅是Synopsys ASIC设计。这是一种高度推荐的技术。
7.5 强制同步器notifier输入为固定值
Verilog和SystemVerilog内置的时序检查($setup、$hold和$setuphold)具有一个可选的notifier输出。当检测到时序违规时,通知器输出从0变为1,然后变为XZ。
大多数ASIC和FPGA触发器模型都是由Verilog用户定义原语(UDP)构建的,通知器信号通常被列为UDP表的一个输入。每当通知器输入切换(由时序违规引起),触发器输出变为未知,这就是在门级触发器模型输出上可见的未知。
至少有一家公司使用的聪明技术是将第一阶段同步器触发器的时序违规通知器强制为一个逻辑电平,以防止它们在仿真期间切换并触发触发器模型的未知输出。
7.6 ASIC和FPGA库单元同步器
如果ASIC和FPGA供应商能够提供完全表征的同步器单元,这些单元可以实例化到设计中,那么CDC设计将变得更加容易。高级ASIC供应商提供:(1)表征的同步器单元。 (2)用于模拟同步器单元的Verilog模型。 (3)生成将同步器单元的建立和保持时间注释为0以避免在信号穿越CDC边界时触发X生成的SDF文件的工具。
我不知道有任何FPGA供应商提供这种能力,但具有前瞻性的FPGA供应商将为他们的高级多时钟设计客户提供这种单元。
7.7 具有随机延迟插入的仿真模型
由多位同事建议的一个有趣的模型,可以综合到正确的同步器设计中,但在仿真中带有可选择的延迟。模型的块图如图33所示,支持此模型的SystemVerilog代码显示在示例6中。
如图33所示,该模型被设计为可以生成一个可综合的同步器模型,或者在仿真中使用可选择的延迟。
IEEE Std 1364.1-2002 Verilog RTL综合标准[6]要求一个符合标准的综合工具在读取任何Verilog模型之前设置SYNTHESIS宏。尽管大多数综合工具已经忽略了IEEE Verilog综合标准的许多要求,但大多数工具已经实现了这个SYNTHESIS宏的要求。
在设置SYNTHESIS宏之前读取此sync2 SystemVerilog代码的工具将选择代码以推断两个触发器的同步器。
不设置SYNTHESIS宏的仿真器将读取sync2模型,忽略旨在综合的代码,并在代码的else
部分进行仿真。
该模型是参数化的,因此可以使用默认参数SIZE为1位宽度用于简单的1位CDC信号,或者可以实例化模型并设置SIZE参数为多位宽度,以便同步器可用于捕获和同步多位总线,例如格雷码计数器。
仿真部分的模型包括一个默认声明的SIZE变量DLY。
标记,上面的逻辑需要理顺
默认情况下,DLY变量被初始化为0,这会导致整个sync2模型以两个触发器的延迟进行仿真,但是可以从测试平台分层设置DLY变量为可重复的1和0的随机值,以使总线上的一些位通过三个触发器阶段,而其他位只通过两个触发器阶段。这可以模拟同步器的行为,其中一些位在比其他位早的时钟边上被捕获,并允许仿真观察设计在多比特数据路径上的小偏斜下的表现如何。
8.0 总结和结论
跨时钟域(CDC)错误可能导致严重的设计故障。通过遵循一些关键指导方针和使用成熟的验证技术,可以避免这些昂贵的故障。
8.1 推荐的1位CDC技术
当在时钟域之间传递1位信号时:
- 在发送时钟域中寄存信号,以消除组合逻辑稳定问题。
- 将信号同步到接收时钟域。可能需要使用多周期路径(MCP)公式。
8.2 推荐的多比特CDC技术
当在时钟域之间传递多个控制或数据信号时,使用以下策略之一:
- 整合 - 在发送时钟域中首先尝试将多个信号合并为1位表示,然后再将信号同步到接收域。
- 使用多周期路径(MCP)公式跨时钟域传递多个信号。
- 使用FIFO(先进先出队列)传递多比特总线,无论是数据还是控制总线。
- 使用格雷码计数器。
8.3 推荐的命名约定和设计分割
- 使用基于时钟的命名约定。
- 尽可能将设计子块分割成完全同步的单时钟设计。
8.4 推荐的多时钟门级CDC仿真解决方案
在门级仿真期间解决CDC X传播仿真问题有多种有用的解决方案:
- 使用Synopsys开关为同步器的第一阶段触发器生成0建立和0保持时间。仅与Synopsys工具兼容。
- 使用多个SDF文件 - 后文描述的良好技术。
- 供应商提供同步器单元和适当的SDF工具 - 如果您的ASIC或FPGA供应商提供模型和工具(很少有供应商提供 - 请要求您的ASIC和FPGA供应商支持此功能)。
- 使用创造性的SystemVerilog模型来模拟同步问题。
本文中描述的技术旨在促进多时钟设计的健壮开发和验证。
9.0 致谢
感谢过去八年来分享有趣多异步时钟CDC设计技术的数百位同事和学生。
10.0 参考文献
[1] Clifford E. Cummings, “Simulation and Synthesis Techniques for Asynchronous FIFO Design,” SNUG 2002 - 可在 www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf 访问。
[2] Clifford E. Cummings, “Synthesis and Scripting Techniques for Designing Multi-Asynchronous Clock Designs,” SNUG 2001 - 可在 www.sunburst-design.com/papers/CummingsSNUG2001SJ_AsyncClk.pdf 访问。
[3] Don Mills & Clifford E. Cummings, “RTL Coding Styles That Yield Simulation and Synthesis Mismatches” SNUG 1999 - 可在 www.sunburst-design.com/papers/CummingsSNUG1999SJ_SynthMismatch.pdf 访问。
[4] Frank Gray, “Pulse Code Communication.” 美国专利号 2,632,058. 1953年3月17日。
[5] Himanshu Bhatnagar, 《Advanced ASIC Chip Synthesis, Second Edition》, Kluwer Academic Publishers, 2002.
[6] “IEEE Std. 1364.1 - 2002 IEEE Standard for Verilog Register Transfer Level Synthesis,” IEEE Computer Society, IEEE, New York, NY, IEEE Std 1364.1-2002.
[7] Mark Litterick, “Pragmatic Simulation-Based Verification of Clock Domain Crossing Signals and Jitter Using SystemVerilog Assertions,” DVCon 2006 - 可在 www.verilab.com/files/sva_cdc_paper_dvcon2006.pdf 访问。
[8] Real Intent, Inc. (白皮书), “Clock Domain Crossing Demystified: The Second Generation Solution for CDC Verification,” 2008年2月 - 可在 www.realintent.com 访问。
[9] Steve Golson, 个人通信。
[10] William J. Dally 和 John W. Poulton, 《Digital Systems Engineering》, Cambridge University Press, 1998.
[11] Wikipedia: http://en.wikipedia.org/wiki/Clock_Domain_Crossing_Verification
11.0 作者和联系信息
Clifford Cummings,Sunburst Design公司的总裁,是一位独立的EDA顾问和培训师,拥有26年的ASIC、FPGA和系统设计经验,以及16年的SystemVerilog、综合和方法论培训经验。
Cummings先生在过去五年中举办了80多场SystemVerilog研讨会和培训课程,并在全球范围内的SystemVerilog NOW!研讨会上担任主讲嘉宾。
Cummings先生参与了IEEE和Accellera SystemVerilog、SystemVerilog Synthesis、SystemVerilog委员会的每一次会议,并发表了40多篇关于SystemVerilog及相关设计、综合和验证技术的论文。
Cummings先生拥有杨百翰大学(Brigham Young University)的电气工程学士学位(BSEE)和俄勒冈州立大学(Oregon State University)的电子工程硕士学位(MSEE)。
Sunburst Design公司提供世界级的Verilog和SystemVerilog培训课程。有关更多信息,请访问www.sunburst-design.com网站。电子邮件地址:cliffc@sunburst-design.com
本文的更新版本可以从网站www.sunburstdesign.com/papers下载(最后更新日期为2008年9月26日)。
12.0 附录
本附录包括了带有确认反馈的MCP(多周期路径)公式和1深2寄存器FIFO(先进先出队列)同步器的源代码。
12.1 通用sync2模型 - 由MCP公式和FIFO同步器使用
sync2模型是MCP公式带有就绪确认设计(源代码在第12.2节)和多比特1深/2寄存器FIFO同步器(源代码在第12.3节)所通用的。
12.2 MCP公式带有就绪确认的源代码
此模型需要第12.1节中展示的sync2模型。
12.3 多比特1深/2寄存器FIFO同步器源代码
此模型需要第12.1节中展示的sync2模型。
// dual-port 2-deep ram