跨时钟域处理解析(三)(Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog)

写在前面

         本文参考自《Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog》--Clifford E. Cummings。

        主要讲述了如何进行跨时钟域设计。正文中,黑字为内容,浅蓝色字体是我的啰嗦。如果需要英文原文文章,可以评论留邮箱给我。

        系列文章:
        跨时钟域处理解析(一)(Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog)

        跨时钟域处理解析(二)(Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog)

        跨时钟域处理解析(三)(Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog)


6.0 命名约定和设计分区

        命名约定有助于确保良好的团队沟通,并有助于使用脚本语言来收集和分组设计中与特定时钟相关联的所有信号。良好的设计划分可以显着减少综合和验证多时钟设计时序的工作。本节将讨论推荐的命名约定和设计分区。

        有两种方法可以解决潜在的 CDC 问题:

                (1) 验证设计是否符合正确的 CDC 规则,

                (2) 避免该问题。

        这两种方法都很有价值,应该用于确保无错误设计。

        第一种方法,即 CDC 设计规则的验证,通常需要使用特殊工具来检查设计是否存在可能的 CDC 违规。当我在 2001 年写第一篇关于多时钟设计的论文时,我不知道市场上有任何工具可以检查 CDC 规则。如今,有许多公司提供此类工具(有关 CDC 验证空间中的公司和工具列表,请参阅 [11])。 第二种方法,避免这个问题,可以通过使用下面概述的一些好的编码指南来完成。

6.1 时钟和信号命名约定

        各种设计团队已经使用了许多有用的时钟和信号命名约定。  

        大纲:使用时钟命名约定来标识设计中每个信号的时钟源。  

        原因:命名约定可帮助所有团队成员识别设计中每个信号的时钟域,并且还可以使用综合脚本中的正则表达式“通配符”使用于时序分析的信号分组更容易。  

        一种行之有效的命名约定要求使用前导前缀字符来标识各种异步时钟域。示例包括:用于微处理器时钟的 uClk、用于视频时钟的 vClk 和用于显示时钟的 dClk。  

        然后每个信号与设计中的某一个时钟域同步,每个信号名称都用前缀字符标记,以标识用于生成该信号的时钟域。例如,任何由 uClk 产生的信号在信号名称中都标有 u 前缀,如 uaddr、udata、uwrite 等。任何由 vClk 产生的信号在信号名称,例如 vdata、vhsync、vframe 等。相同的信号命名约定用于设计中任何其他时钟生成的所有信号。 

        使用这种技术,设计团队中的任何工程师都可以轻松识别设计中任何信号的时钟域源,并直接使用这些信号或通过适当的同步传递信号,以便在新的时钟域中使用这些信号。  

        确切的命名约定并不重要,但至关重要的是项目中的每个工程师都同意遵守团队选择的命名约定。命名约定将显着提高设计团队的生产力。

        这个每个公司基本上都有自己的约定,规范些的公司还会以文件的形式发布,要求所有设计人员都遵守。  

6.1.1 无命名约定的多时钟/多源模块

        如果您的团队不使用任何特定的面向时钟的信号命名约定,并且如果允许模块具有多个时钟输入,则始终存在 CDC 分析工具可能设置不正确的危险,并且很容易错过不良的 CDC 设计实践.。 

        即使您的团队可以使用良好的 CDC 分析工具,我也强烈建议您采取几个简单的步骤,以便更轻松地识别和调试潜在的 CDC 设计问题的分析和识别。

6.2 每个时钟域的时序验证

        要验证任何设计的时序,必须验证设计中的每个时钟域是否满足时序要求。尽管工具在过去十年中有所改进,可以帮助自动分析和验证不同时钟域中的信号,但使用良好的分区和命名约定进行多时钟设计仍然是一种很好的做法。  

        通过对设计进行分区以允许每个模块只允许一个时钟,静态时序分析对于设计中的每个域来说变得非常容易。  

6.3 面向时钟的设计分区

        一些最简单和最好的设计分区方法是在时钟边界使用设计分区来实现的。  

        大纲:每个模块只允许一个时钟[9]。  

        原因:在单时钟模块或单时钟模块组上更容易完成静态时序分析和创建综合脚本。  

        例外:将来自所有不同时钟域的信号连接在一起的顶级模块自然会将所有时钟作为该模块的输入。尽量减少您的多时钟验证工作,只允许顶层模块有多个时钟输入。  

        大纲:将设计块划分为一个时钟模块。  

        原因:完全同步的子块的时序验证可以使用 STA(静态时序分析)工具轻松验证,并将设计块划分为多个一个时钟域子块将大型复杂的时序分析任务转换为多个完全同步的单时钟设计。  

        大纲:创建同步器模块以将信号从一个时钟域传递到另一个时钟域,并且每个同步器模块只允许一个时钟。  

        原因:假设从一个时钟域传递到另一个时钟域的任何信号最终都会遇到建立和保持时间问题。隔离 CDC 边界逻辑可以显着减少多时钟设计的设计和验证工作。  

        在大多数情况下,同步器模块将是设计中唯一会遇到有意建立和保持时间违规的模块。在异步时钟域之间传递信号时,会发生时序违规,这就是必须在设计中添加同步器的全部原因。

        设计尽量模块化,细化,然后每个模块都只使用一个时钟,最后通过顶层模块(可以有数个层级)来将子模块汇总,从而将CDC问题控制在顶层模块,有效地减少问题发生的概率。

        考虑具有三个时钟域的示例设计,标记为 aClk、bClk 和 cClk,如图 30 所示。在该设计中,所有 aClk 设计块都被组合到一个 aClk 逻辑块中。所有的 bClk 设计块都被组合到一个 bClk 逻辑块中,同样我们创建了一个 cClk 逻辑块。任何源自异步的信号时钟域在允许驱动另一个逻辑块的输入之前通过同步器模块。 

6.3.1 时钟分区模块的时序分析

        使用面向时钟的设计分区策略,每个设计块的所有输入和输出都完全同步到一个时钟。这是使用静态时序分析 (STA) 工具验证的最简单的设计类型,因为设计中没有错误路径。  

        将在每个时钟域内计时的所有设计模块组合在一起。应该为设计中的每个时钟域形成一个组。这些组将进行时序验证,就好像每个组都是单独的、完全同步的设计。对于每个时钟域,我们有一个设计模块,我们可以轻松执行最坏情况(最大时间/设置时间检查)时序分析和最佳情况(最小时间/保持时间检查)时序分析。  

        同样使用这种面向时钟的分区策略,每个 CDC 边界都使用同步器模块进行了隔离。每个同步器模块仅包括由 ASIC 或 FPGA 供应商(首选)提供的同步器单元,或者使用成对连接的触发器构建以形成同步器等效单元。  

        如果 ASIC 或 FPGA 供应商提供同步器单元并在设计中实例化,则无需验证这些模块的建立和保持时间,因为供应商应该已经创建了不违反建立或保持的单元布局触发器阶段之间的时间。

        如果同步器是从 RTL 代码综合的,最重要的是执行最佳情况时序分析,以确保触发器不会靠得太近,以免第一级的输出变化太快满足第二阶段输入的保持时间要求。一位同事最近指出,还应该执行最坏情况时序分析,以防布局工具碰巧将两个同步器触发器放置在 ASIC 或 FPGA 芯片上相距很远的地方。我同意这个更新的建议。  

        由于单独同步器的分区,门级模拟可以更容易地配置为忽略每个同步器第一阶段的建立和保持时间违规。  

        RTL 同步器的静态时序分析需要简单的 set_false_path 命令来移除 STA 的输入。我们知道同步器的输入端存在计时问题,这就是使用同步器的原因。  

        通过划分设计和同步器块以允许每个模块只允许一个时钟,静态时序分析变得非常容易执行。用于解决多个时钟域问题的综合脚本命令现在变成了分组、识别错误路径和执行最小-最大时序分析的问题。

6.4 用 MCP 方法进行分区

        在时钟边界处将设计划分为单独的设计块和同步器块在大多数情况下效果很好,但如果需要使用 MCP 公式在时钟域之间传递多个信号,则传递到设计块的一些信号可能会出现来自不同的时钟域,如图 31 所示。 

        如果设计中的信号使用了基于时钟的命名约定,那么具有异步输入的设计模块仍然可以轻松计时。在有问题的设计块上执行 STA 之前,只需从分析中排除异步输入。  

        通常,只有同步器和 MCP 公式数据路径的输入需要“set_false_path”命令。如果使用时钟前缀命名方案,则可以使用通配符轻松识别所有异步输入。在图 31 中,要从 bClk 逻辑块内的 STA 中排除 adata 总线,请先执行以下命令:

                set_false_path -from { a* } 

        该命令应该足以消除来自 bClk STA 的所有异步输入。 

7.0 多时钟门级仿真问题

        当同步器识别CDC信号上的设置和保持时间违规时,数字仿真模型通常会生成X。这通常会导致门级仿真失败。存在哪些技术来解决此问题?  

        如 6.3.1 节所述,通过同步器跨越时钟边界的信号将遇到建立和保持违规。这就是为什么在设计中添加同步器的原因,以过滤掉变化太接近接收时钟域时钟信号上升沿的信号的亚稳定性效应。  

7.1 同步器门级CDC仿真问题 

        在多时钟设计上进行栅极级仿真时,触发器的ASIC库模型使用建立时间和保持时间表达式进行建模,以匹配实际触发器的时序规格。ASIC库通常对触发器进行建模,以便在发生时序违规时驱动触发器输出上的X(未知数)。仿真栅极级同步器时,违反建立时间和保持时间可能会导致 ASIC 库发出建立时间和保持时间错误消息,并且有问题的信号经常被驱动到 X 值。这些X值传播到设计的其余部分,在尝试验证整个栅极级设计的功能时会引起问题,如图31所示。 

7.2 从门级模拟中消除 X 传播的策略

        在过去的10年中,许多同事与我分享了许多策略,以解决每次信号违反同步器第一阶段的设置或保持时间时与X的不必要传播有关的问题。 

        由于 X 传播发生在违反设置或保持时间时,因此几乎所有解决此问题的方法都涉及将设置和保持时间更改为 0,以便不会违反设置或保持时间,因此不会发生 X 传播。  

        有些方法是坏的,有些是好的。以下是为解决X传播问题而考虑的一些策略。  

7.2.1 关闭时序检查的模拟器命令

        大多数 SystemVerilog 模拟器都有一个命令选项来忽略所有时序检查,但这也会忽略设计其余部分所需的时序检查。  

7.2.2 将触发器建立和保持时间更改为 0

        对于同步器中使用的任何 ASIC 库触发器,可以将设置和保持时间设置更改为零,但这将导致该类型触发器的所有实例的所有设置和保持时间检查都设置为零,包括您可能希望用于测试设计其余部分的触发器。  

7.2.3 复制和修改新的触发器模型

        您可以从ASIC库制作触发器的副本,并将它们存储到具有不同名称的新SystemVerilog库中,将所有建立时间和保持时间设置为零,然后修改设计门级网表,用修改后的库触发器替换所有第一级同步器ASIC库触发器,而无需时序检查,但这可能是一个容易出错且繁琐的过程,每次生成新网表时可能都必须重复该过程,或者每次生成新网表时都必须重复该过程它可能需要创建一个生成文件和脚本,以便在每次生成新的网表时自动进行修改。  

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

        对同步器的第一级触发器的输出使用创造性的命名约定可能会使通配符表达式能够轻松地回溯注释所有第一阶段触发器 SDF 设置,并使用很少的 dc_shell-t 命令将时间值保持为零。  如果使用 Synopsys DesignCompiler 工具完成设计,则此技术有效,但非 Synopsys 流呢?  

7.3 消除 X 传播的其他策略

        第7.2节至第7.2.4节中描述的所有策略都在我2001年给出的第一篇多时钟设计论文中进行了分享。在最初的演示之后,许多工程师站出来分享了从门级仿真中去除X传播的其他技术。来自至少三家公司的工程师对该技术的描述与###一节中的描述非常相似(向参加圣何塞SNUG-2001的工程师致敬)。  

        从那时起,来自许多公司的其他工程师分享了其他技术。本节将介绍这些技术,我非常感谢所有工程师,他们每年都继续与我分享有趣的技术。向大家致敬! 

7.3.1 使用多个 SDF 文件

        请记住,消除不需要的 X 传播的关键是强制同步器输入的建立时间和保持时间为 0,从而消除同步器输入上所有可能的建立和保持时间冲突。  

        许多工程师告诉我,他们实际上生成了两个SDF文件。第一个 SDF 文件具有整个设计的所有实际延迟,包括精确的建立时间和保持时间。然后,工程师生成第二个 SDF 文件,其中仅包含第一级触发器。在此文件中,建立时间和保持时间设置为 0。一些工程师手动构建此文件,而其他工程师则使用脚本生成此文件。  

        然后,工程师使用$sdf_annotate命令读取第一个SDF文件。然后,它们读取第二个 SDF 文件,该文件覆盖了第一级同步器数据输入的建立时间和保持时间。读取两个 SDF 文件时,每个实例的最后一个 SDF 文件优先。所有时序都进行了准确的注释,然后修改了第一级同步器的时序检查。  

        这是一种聪明的方法,可用于生成 SDF 文件的任何工具流。 

7.3.2 带有支持 SDF

        生成工具的供应商同步器单元 其他工程师已经告诉过解决X传播问题的好方法,但该方法需要(a)控制单元库,或(b)与您的ASIC供应商建立良好的工作关系。 

        此技术要求创建一个单独的同步器单元,并在两个触发器阶段之间具有适当的放置关系。要使此方法正常工作,供应商必须提供:

                (1) 实际的同步器单元 - 这些将被固定到设计中。

                (2) 用于模拟的同步器单元的系统验证模型。

                (3) SDF 文件生成工具,这些工具将为同步器单元生成具有 0 设置和 0 保持的 SDF 文件。  

        如果供应商可以提供此单元和这些功能,则只需生成一个 SDF 文件,并对同步器单元进行适当的时序检查。  

        任何提供此功能的FPGA供应商的ASIC都在为他们的客户群带来巨大的帮助。我听说一些ASIC供应商提供此功能。我不知道有任何FPGA供应商提供这种功能。认识到大多数现代设计都是多时钟设计,我强烈敦促所有ASIC甚至所有FPGA供应商为同步器单元提供适当的仿真和SDF文件工具支持。

7.3.3 具有内置同步器支持的供应商

        如果有人知道提供此支持的供应商,请通过适当的联系信息让我知道供应商是谁,我将定期更新本白皮书,以表彰向我们(设计社区)提供此功能的供应商。  

        供应商列表: (截至本文,未列出任何供应商) 

7.4 用于门级 CDC 模拟的多个 SDF 文件

        在2001年我第一次做多时钟演示后,来自至少三家不同公司的工程师在我演讲后立即分享了以下解决门级仿真中X传播的出色技术。  

        该技术涉及写出完整的SDF时序文件,然后手动或使用脚本,为所有同步器模块的第一级触发器生成第二个SDF文件。第二个 SDF 文件将所有设置和保持时间设置为 0,然后使用 $sdf_annotate 命令将两个 SDF 文件应用于设计。第一个 SDF 文件将所有实际时序注释为整个设计,然后读取第二个 SDF 文件以覆盖第一级同步器的建立时间和保持时间。  

        这种技术的优点是,它可以使用所有工具用于所有设计,而不仅仅是 Synopsys ASIC 设计。这是一项强烈推荐的技术。

7.5 强制同步器通知器输入为固定值

        Verilog 和 SystemVerilog 设置的内置计时检查和保持时间检查($setup, $hold和$setuphold)具有可选的通知程序输出。每当检测到时序冲突时,此通知程序输出就会从 0-1-XZ 切换。 

        大多数 ASIC 和 FPGA 触发器型号都是从 Verilog 用户定义基元 (UDP) 构建的,通知器信号通常被列为 UDP 表的输入之一。每当通知器输入切换(由时序违规引起)时,触发器输出就会变为未知,而该未知值在栅极级触发器型号的输出上可见。这些第一级触发器型号上的通知程序可以强制到逻辑电平,以防止它们在仿真过程中切换并导致触发器输出未知。  

        至少一家公司使用的一种聪明技术迫使第一级同步器触发器的时序违规通知器被强制到一个逻辑电平,这样它们就永远无法切换和触发X进入触发触发器模型。 

7.6 ASIC 和 FPGA 库单元同步器

        如果ASIC和FPGA提供商能够提供可以实例化到设计中的完全表征的同步器单元,那么CDC设计可以更容易地完成。

        高级ASIC供应商提供:

                (1) 表征的同步器单元。

                (2) 用于模拟同步器单元的 Verilog 模型。

                (3) SDF 发生器,用于生成 SDF 文件,这些文件将同步器单元上的建立和保持时间注释为 0,以避免在信号跨越 CDC 边界时违反设置或保持时间时生成 X。  

        据我所知,没有FPGA提供商提供这种功能,但具有前瞻性思维的FPGA提供商会为其先进的多时钟设计客户提供此类单元。 

7.7 具有随机延迟插入的仿真模型

        多个同事提出了一个有趣的模型,该模型综合到正确的同步器进行设计,但以随机周期延迟进行仿真。

        该模型的框图如图 33 所示,支持该模型的 SystemVerilog 代码如示例 6 所示。 

      

        从框图中可以看出,该模型旨在生成可合成的同步器模型,或用作具有可选延迟的仿真模型。  

        IEEE Std 1364.1-2002 Verilog RTL Synthesis Standard[6]要求在读取任何Verilog模型之前,兼容的合成工具设置SYNTHESIS宏。尽管大多数综合工具在很大程度上忽略了IEEE Verilog综合标准的许多要求,但大多数工具都实现了这个不错的综合宏要求。  

        在读取此 sync2 SystemVerilog 代码之前设置 SYNTHESIS 宏的工具将选择代码来推断两个触发器同步器。  

        未设置 SYNTHESIS 宏的模拟器将读取 sync2 模型,忽略用于可合成模型的代码,并在代码的 "else" 部分中模拟模型。 模型已参数化,因此可以使用相同的模型与宽度为 1 位的默认参数 SIZE 一起用于简单的 1 位 CDC 信号,或者可以使用 SIZE 实例化模型 参数设置为多位宽度,以便同步器可用于捕获和同步多位总线,例如格雷码计数器。 

        模型的模拟部分包括一个名为 DLY 的 SIZE 变量的默认声明。默认情况下,DLY 变量初始化为 0,这会导致整个 sync2 模型以两个触发器延迟的默认值进行模拟,但 DLY 变量可以从测试平台分层设置为可重现的 1 和 0 的随机值,从而导致一些总线中的位通过三个触发器级,而其他位仅通过两个触发器级。这可以对一组同步器的行为进行建模,其中一些位在比其他位更早的时钟边沿被捕获,并允许仿真观察设计在多位数据路径中的小偏斜下的表现如何。 

8.0 总结与结论

        时钟域交叉 (CDC) 错误会导致严重的设计失败。通过遵循一些关键指南并使用完善的验证技术,可以避免这些代价高昂的故障。  

8.1 推荐的 1 bit CDC 技术

        在时钟域之间传递一bit时:

  • 在发送时钟域中注册信号以消除组合稳定。
  • 将信号同步到接收时钟域。可能需要多循环路径 (MCP) 公式。  

8.2 推荐的多bit CDC 技术

        在时钟域之间传递多个控制或数据信号时,请使用以下策略之一:

  • 合并 - 在将信号同步到接收域之前,首先尝试在发送时钟域中将多bit信号组合成 1 bit表示。
  • 使用多周期路径 (MCP) 公式跨时钟域传递多个信号 。
  • 使用 FIFO 传递多位总线,数据或控制总线。
  • 使用格雷码计数器。  

8.3 推荐的命名约定和设计分区

        使用基于时钟的命名约定。  尽可能将设计子块划分为完全同步的 1 时钟设计。 

8.4 多时钟门级 CDC 仿真的推荐解决方案

对于门级仿真期间的 CDC X 传播仿真问题,有多种有用的解决方案:

  • 使用 Synopsys 开关为同步器上的第一级触发器生成 0-setup 和 0-hold 时间。仅适用于 Synopsys 工具。
  • 使用多个 SDF 文件 - 本节稍后介绍的好技术。
  • 供应商提供同步器单元和适当的 SDF 工具 - 如果您的 ASIC 或 FPGA 供应商提供模型和工具,这是一个很好的解决方案(很少这样做 - 要求您的 ASIC 和 FPGA 供应商支持此功能)
  • 使用创造性的 SystemVerilog 模型来模拟同步问题。  

本文中描述的技术旨在促进多时钟设计的稳健开发和验证。  

猜你喜欢

转载自blog.csdn.net/wuzhikaidetb/article/details/123521798