Clock Domain Crossing (CDC) Design & VerificationTechniques Using SystemVerilog(PartⅠ)

105 篇文章 13 订阅

                                                                          
                                                                     摘要
        重要的设计考虑因素要求在跨时钟域(CDC)边界处仔细构建多时钟设计。本文详细介绍了一些最新的策略和最著名的方法,以解决一个和多个信号跨越CDC边界的问题。论文中包括与CDC验证相关的技术,以及用于在时钟域之间传递多个控制信号的有趣的2深度FIFO设计。尽管本文中描述的设计方法通常可以使用任何HDL来实现,但示例是使用有效的SystemVerilog技术来展示的。

2.0 亚稳态
        亚稳态是指在设计的正常操作期间的某个时刻,在某个持续时间内不呈现稳定的0或1状态的信号。在多时钟设计中,亚稳态是无法避免的,但亚稳态的有害影响可以被抵消。

                                                 图1-异步时钟和同步失败
        引用Dally和Poulton关于转移性的书[9]:“当用时钟对不断变化的数据信号进行采样时……事件的顺序决定了结果。事件之间的时间差越小,确定哪个先发生的时间就越长。当两个事件发生得非常接近时,决策过程可能需要比分配的时间更长的时间,并且会发生同步失败。"
        图1显示了当在一个时钟域中生成的信号被采样到离第二个时钟区域的时钟信号的上升沿太近时发生的同步失败。同步失败是由于输出变得亚稳,并且在必须再次采样时没有收敛到合法的稳定状态。

2.1为什么亚稳态是一个问题?
        那么,为什么亚稳态是个问题呢?图2显示,通过接收时钟域中的附加逻辑的亚稳态输出可能导致非法信号值在整个设计的其余部分传播。由于CDC信号可以波动一段时间,所以接收时钟域中的输入逻辑可以将波动信号的逻辑电平识别为不同的值,并因此将错误信号传播到接收时钟区域中

                                 图2-亚稳态bdat1输出在整个设计过程中传播无效数据
        在任何设计中使用的每个触发器都有指定的setup和hold时间,或者在上升时钟沿前后不允许数据输入改变的时间。这个时间窗口被指定为设计参数,精确地防止数据信号与另一个同步信号变化得太近,从而可能导致输出变为亚稳态。

3.0 同步器
        在时钟域之间传递信号时,需要问的一个重要问题是,我是否需要对从一个时钟域传递到另一个时钟域的信号的每个值进行采样?

3.1两种同步场景
在跨越CDC边界传递信号时,有两种情况是可能的,确定哪种情况适用于您的设计很重要:
(1) 允许错过在时钟域之间传递的样本
(2) 必须对在时钟域之间传递的每个信号进行采样
        第一种情况:有时不需要对每个值进行采样,但采样值的准确性很重要。一个例子是在标准异步FIFO设计中使用的一组格雷码计数器。在设计合理的异步FIFO模型中,同步格雷码计数器不需要从相反的时钟域捕获每个合法值,但至关重要的是,采样值要准确,以识别何时出现满和空情况。
        第二种情况:在允许更改CDC信号之前,必须正确识别或识别并确认CDC信号。在这两种情况下,CDC信号将需要某种形式的同步到接收时钟域。

3.2 Two flip-flop synchronizer(两个触发器同步)
        再次引用Dally和Poulton[9]关于同步器的内容:“同步器是一种对异步信号进行采样并输出转换与本地时钟或采样时钟同步的信号版本的设备。”
        数字设计师使用的最简单、最常见的同步器是两级触发器同步器,如图3所示。
        第一触发器将异步输入信号采样到新的时钟域中,并等待一个完整的时钟周期以允许第一级输出信号上的任何亚稳性衰减,然后通过相同的时钟将第一级信号采样到第二级触发器中,其预期目标是阶段2信号现在是一个稳定有效的信号,同步并准备在新的时钟域内分发。

                                                        图3 - 两级同步触发器
        理论上,当信号被计时到第二级以使第二级输出信号也变为亚稳时,第一级信号仍然足够亚稳是可能的。同步故障间隔时间(MTBF)概率的计算是多个变量的函数,包括用于生成输入信号和为同步触发器计时的时钟频率。在Dally和Poulton[9]中可以找到对MTBF计算的一种描述。对于大多数同步应用,双触发器同步器足以消除所有可能的亚稳态

3.3 MTBF-故障前平均时间
        对于大多数应用,对任何跨越CDC边界的信号进行平均故障前时间(MTBF)计算是很重要的。从这个意义上说,故障意味着一个信号被传递到同步触发器,在第一级同步器触发器上变为亚稳态,并且在一个周期后当它被采样到第二级同步器触发时继续是亚稳态。由于信号在一个时钟周期后没有稳定到已知值,因此当采样并传递到接收时钟域时,信号仍然可以是亚稳的,从而导致相应逻辑的潜在故障。
        在计算MTBF数时,较大的MTBF数表示潜在故障之间的时间间隔较长,而较小的MTBF数则表示亚稳态可能频繁发生,类似地会导致设计中的故障。
        Dally和Poulton[9]给出了一个很好的方程,对可以用来计算同步器电路MTBF的计算进行了非常彻底的分析。在不重复等式和分析的情况下,应该指出的是,直接影响同步器电路MTBF的两个最重要的因素是,采样时钟频率(信号被采样到接收时钟域的速度有多快)和数据变化频率(CDC边界的数据变化速度有多快)。

                                        图4-造成MTBF短值的主要因素
         从上面的部分方程可以看出,在高速设计中,或者当采样数据变化更频繁时,故障发生的频率更高(MTBF更短)。

3.4 Three flip-flop synchronizer(三级触发器同步器)
        对于一些非常高速的设计,双触发器同步器的MTBF太短,增加第三个触发器以将MTBF增加到令人满意的持续时间。当然,是由设计的架构师决定的。

                                                 图5-用于高速设计的三触发器同步器

3.5 Synchronizing signals from the sending clock domain(同步来自发送时钟域的信号)
        关于CDC设计的常见问题:在将信号传递到接收时钟域之前,寄存来自发送时钟域的信号是个好主意吗?问题中隐含的是CDC信号将被同步到接收时钟域的假设;因此,它们不需要在发送时钟域中进行同步。这种合理化是不正确的,通常需要在发送时钟域中寄存信号
        考虑一个示例,其中发送时钟域中的信号在传递到接收时钟域之前没有寄存,如图6所示。

                                                        图6-跨越CDC边界发送的未寄存信号
        在这个例子中,来自发送时钟域的组合输出可能在CDC边界处经历组合逻辑毛刺。这种组合沉降有效地增加了数据变化频率,可能会产生振荡数据的小突发,从而增加了在变化时可以采样的边沿数量,相应地增加了采样变化数据和生成亚稳信号的可能性。
3.6 Synchronizing signals into the receiving clock domain(将信号同步到接收时钟域)
        发送时钟域中的信号在被传递到CDC边界之前应该被同步来自发送时钟域的信号同步减少了可以在接收时钟域中采样的边沿数量,有效地降低了MTBF方程中的数据变化频率,从而增加了计算故障之间的时间(有关数据变化频率对MTBF的影响的描述,请参阅第3.3节)。

                                                 图7-CDC边界发送的寄存信号

         在图7中,aclk逻辑在被传递到bclk域之前,在adat触发器上进行设置。adat触发器过滤掉触发器输入(a)上的组合逻辑毛刺,并将干净信号传递给bclk逻辑。

4.0 Synchronizing fast signals into slow clock domains(将快速信号同步到慢速时钟域)
        如第3.1节所述,如果CDC信号在时钟域之间传递时不能跳过,那么当信号在时钟域之间传递的时候,考虑信号宽度或同步技术是很重要的。与同步器相关的一个问题是,来自发送时钟域的信号可能在被采样之前改变两次值,或者可能过于接近较慢时钟域中的采样边沿。在信号从一个时钟域发送到另一个时钟域的任何时候都必须考虑这种可能性,并且必须确定遗漏的信号是否是所讨论的设计的问题。
当不允许遗漏样本时,有两种解决问题的通用方法:
        (1) 一种开环解决方案,可确保在没有确认的情况下捕获信号。
        (2) 一种闭环解决方案,需要确认接收到跨越CDC边界的信号。
本节将讨论这两种解决方案。
4.1 Requirement for reliable signal passing between clock domains(时钟域之间可靠信号通过的要求)
        如果较快时钟域是较慢时钟域的频率(或更高)的1.5倍,则将较慢的控制信号同步到较快的时钟域通常不是问题,因为较快的时钟信号将对较慢的CDC信号采样一次或多次。认识到将较慢信号采样到较快时钟域比将较快信号采样到较慢时钟域引起的潜在问题更少,设计者可以利用这一事实,使用简单的双触发器同步器在时钟域之间传递单个CDC信号。
4.1.1 The "three edge" requirement(三边沿要求)
        Mark Litterick[4]指出,当通过双触发器同步器在时钟域之间传递一个CDC信号时,CDC信号必须比接收域时钟周期的周期宽度的1-1/2倍宽。Littereick将这一要求描述为“输入数据值必须在三个目标时钟边沿保持稳定。”对于超长的源和目的时钟频率,这一要求可能会安全地放宽到接收时钟域周期时间的1-1/4倍或更短,但“三边沿”准则是最安全的初始设计条件,并且通过使用SystemVerilog断言比在模拟期间动态测量CDC信号的分数宽度更容易证明。“三边沿”要求实际上适用于开环和闭环解决方案,但闭环解决方案的实现会自动确保所有CDC信号至少检测到三个边沿。
4.2 Problem - passing a fast CDC pulse(通过快速CDC脉冲)
        考虑严重缺陷的情况,其中发送时钟域的频率高于接收时钟域,并且CDC脉冲在发送时钟区域中只有一个周期宽。如果CDC信号仅一个快速时钟周期脉冲,则CDC信号可能在较慢时钟的上升沿之间变高和变低,并且不会被捕获到较慢时钟域中,如图8所示。

                                        图8-同步期间遗漏的短CDC信号脉冲
4.3 Problem - sampling a long CDC pulse - but not long enough!(问题-采样一个长的CDC脉冲-但不够长)
        考虑发送时钟域向接收时钟域发送比接收时钟频率的周期稍宽的脉冲的有点不直观和有缺陷的情况。在大多数情况下信号将被采样并通过,但是存在CDC脉冲将在太靠近接收时钟域的两个上升时钟边沿处改变的微小但真实的可能性,并且从而违反第一时钟边沿上的建立时间并且违反第二时钟边沿的保持时间并且不形成预期脉冲。这种可能的故障如图9所示。

                                 图9-违反目的地setup和hold时间的边际CDC脉冲

 4.4 Open-loop solution - sampling signals with synchronizers(开环解决方案-使用同步器对信号进行采样)
        这个问题的一个潜在解决方案是在超过采样时钟周期时间的一段时间内断言CDC信号,如图10所示。如第4.1.1节所述,最小脉冲宽度是接收时钟频率周期的1.5倍。假设CDC信号将被接收器时钟至少采样一次,并且可能采样两次。
        当相对时钟频率固定并正确分析时,可以使用开环采样
        优点:开环解决方案是通过CDC边界传递信号的最快方式,无需确认接收到的信号。
        缺点:与开环解决方案相关的最大潜在问题是,另一位工程师可能会将该解决方案误认为是通用解决方案,或者设计要求可能会发生变化,而工程师可能无法重新分析原始的开环解决方案。
通过在模型中添加SystemVerilog断言来检测输入脉冲是否未能超过“三边沿”设计要求,可以将此问题降至最低。


                                        图10-延长脉冲以保证对控制信号进行采样
4.5 Closed loop solution - sampling signals with synchronizers(闭环解决方案-带同步器的采样信号)
        这个问题的第二个潜在解决方案是发送使能控制信号,将其同步到新的时钟域中,然后将同步信号通过另一个同步器返回到发送时钟域作为确认信号。
        优点:同步反馈信号是一种非常安全的技术,可以确认第一个控制信号已被识别并采样到新的时钟域中。
        缺点:在允许控制信号改变之前,在两个方向上同步控制信号可能会有相当大的延迟。

                                                图11-带有反馈的信号以确认接收
5.0 Passing multiple signals between clock domains(在时钟域之间传递多个信号)
        在时钟域之间传递多个信号时,简单的同步器无法保证数据的安全传递。工程师在进行多时钟设计时经常犯的一个错误是将同一事务中所需的多个CDC位从一个时钟域传递到另一个时钟域,并忽略了CDC位同步采样的重要性。
        问题在于,与一个时钟同步的多个信号将经历小的数据变化偏斜,该偏斜偶尔可以在第二时钟域中的不同上升时钟沿上采样。
        即使我们能够完美地控制和匹配多个信号的布线长度,上升和下降时间的差异以及整个die的工艺变化也可能会引入足够的偏斜,从而导致在其他精心匹配的布线上出现采样失败。必须采用多位CDC策略来避免多位值的偏斜采样。
5.1 Multi-bit CDC strategies(多比特CDC策略)
为了避免多位CDC偏斜的采样场景,我将多位CDC策略分为三大类:
(1) 多位信号合并
        在可能的情况下,将多个CDC位合并为1位CDC信号。
(2) 多周期路径方案
        使用同步加载信号安全地通过多个CDC位。
(3) 使用格雷码传递多个CDC比特。
        这些策略中的每一个都将在本节的剩余部分中详细介绍。
5.2 Multi-bit signal consolidation(多比特信号合并
        在可能的情况下,将多个CDC信号合并为1位CDC信号。问自己一个问题,我真的需要多个比特来控制跨越CDC边界的逻辑吗?
        简单地在所有CDC位上使用同步器并不总是足够好,如以下示例所示。如果控制信号的顺序或对齐是重要的,则必须注意将信号正确地传递到新的时钟域中。本节中显示的所有示例都过于简单,但它们非常模仿真实设计中经常出现的情况。

5.3 Problem - Two simultaneously required control signals(同时需要两个控制信号)
        在图12所示的简单示例中,接收时钟域中的寄存器需要load信号和enable信号才能将数据值加载到寄存器中。如果load信号和enable信号都在同一发送时钟沿上被驱动,则控制信号之间的小偏斜可能导致两个信号被同步到接收时钟域内的不同时钟周期中。在这些条件下,数据将不会加载到寄存器中。


                                        图12-问题-在时钟域之间传递多个控制信号
5.3.1 Solution - Consolidation(解决方案-整合)
        第5.3节中问题的解决方案很简单,即合并控制信号。如图13所示,仅从一个 load-enable信号驱动接收时钟域中的load 和 enable寄存器输入信号。合并将消除两个控制信号在时间上偏移到达的可能性。

                                 图13-解决方案-在时钟域之间传输之前合并控制信号
5.4 Problem - Two phase-shifted sequencing control signals(两个相移序列控制信号)
        图14中的图表显示了两个使能信号b_ld1和b_ld2,它们从发送时钟域依次驱动到接收时钟域,以控制流水线数据寄存器的使能输入。问题在于,在第一时钟域中,b_ld1控制信号可能在b_ld2控制信号生成之前稍微终止,并且接收时钟的上升沿可能出现在b_ld1和b_ld2控制脉冲之间的微小间隙中,导致在接收时钟域的使能控制信号链中形成一个周期的间隙。这将导致a2数据值被第二寄存器遗漏。

                                        图14-问题-在时钟域之间传递顺序控制信号
5.4.1 Solution - consolidation and an extra flip-flop(整合和一个额外的触发器)
        如图15所示,这个问题的解决方案是只向接收时钟域发送一个控制信号,并在接收时钟区域内生成第二个相移流水线使能信号

                         图15-解决方案-在新时钟域中生成正确序列信号的逻辑
5.5 Problem - Multiple CDC signals(多个CDC信号)
        图16中的图表显示了两个编码的控制信号在时钟域之间传递。如果两个编码信号在采样时略微偏斜,则在接收时钟域中的一个时钟周期内可能产生错误的解码输出

                                        图16-问题-时钟域之间传递的编码控制信号
5.5.1 Solutions for passing multiple CDC signals (通过多个CDC信号的解决方案)
多周期路径(MCP)方案和FIFO技术可用于解决与传递多个CDC信号有关的问题。
MCP方案的描述和定义见第5.6节,至少有两种多周期路径(MCP)方案可用于解决此问题:
(1) 闭环-MCP方案,带反馈。
(2) 闭环-MCP方案,带有确认反馈。
MCP方案的实现技术将在下一节开始介绍。
还有至少两种FIFO策略可以作为这个问题的闭环解决方案:
(1) 异步FIFO实现。
(2) 2-deep  FIFO实现。
FIFO实现技术从第5.8节开始描述。

                                        图17-在时钟域之间传递同步使能脉冲的逻辑
5.6 Multi-Cycle Path (MCP) formulation(多周期路径(MCP)方案)
        使用MCP方案是用于安全地传递多个CDC信号的常用技术。MCP方案是指将未同步的数据发送到与同步的控制信号配对的接收时钟域。同时发送数据和控制信号,允许数据建立在目的寄存器的输入上,同时在控制信号到达目的寄存器的加载输入之前同步两个接收时钟周期。
优势:
(1) 发送时钟域不需要计算在时钟域之间发送的适当脉冲宽度。
(2) 发送时钟域只需要将使能切换到接收时钟域,以指示数据已经通过并准备好加载。
        使能信号不需要返回到其初始逻辑电平。该策略在没有同步的情况下传递多个CDC信号,并同时将同步的使能信号传递到接收时钟域。在同步使能通过同步并到达接收寄存器之前,不允许接收时钟域对多位CDC信号进行采样。
        这种策略被称为多周期路径方案[8],因为未同步的数据字被直接传递到接收时钟域,并保持多个接收时钟周期,从而允许在未同步数据字改变之前将使能信号同步并识别到接收时钟域。因为未同步的数据在被采样之前被传递并保持稳定多个时钟周期,所以采样值不会变得亚稳。
5.6.1 MCP formulation using a synchronized enable pulse(使用同步使能脉冲的MCP方案)
        在时钟域之间传递同步使能信号的最常见方法可能是使用传递到同步脉冲发生器的翻转使能信号,以指示可以在下一个接收时钟边沿捕获未同步的多周期数据字,如图18所示。
        这种同步使能脉冲产生的一个关键特征是输入信号的极性无关紧要。在图18中,d输入在周期1中被切换为高电平,到周期4时,高信号已经通过三个同步触发器传播。在周期3中,q2和q3触发器的输出具有不同的极性,使得同步使能脉冲在同一周期中在异或门的输出上形成。类似地,d输入在周期7中被切换为低,并且到周期10,高信号已经通过三个同步触发器传播。再次在周期9中,q2和q3触发器的输出具有不同的极性,导致同步使能脉冲在异或门的输出上形成。

                                                         图18-同步脉冲生成逻辑
        由于第5.0节中描述的所有MCP方案都使用同步使能脉冲生成电路,因此创建并使用较小的等效符号来表示同步使能脉冲生成电路被认为是有用的。等效符号如图19所示。

                                         图19-同步使能脉冲生成逻辑和等效符号
        除了生成任何d输入极性的脉冲关断之外,同步使能脉冲生成电路还具有跟随延迟了三个时钟周期的d输入的q输出。q输出经常被用作反馈信号,并且作为确认信号通过发送时钟域中的另一个同步使能脉冲生成电路。图20显示了典型的发送-接收触发脉冲生成设计。

                                         图20-多循环路径(MCP)方案触发脉冲生成
        使用这种技术,需要接收时钟域具有适当的逻辑以在检测到脉冲时捕获数据,因为脉冲对于每个多周期数据字仅一个接收时钟周期有效
5.6.2 Closed-loop - MCP formulation with feedback(闭环-带反馈的MCP方案)
        使用MCP方案时的一个重要技术是将使能信号作为确认信号传递回发送时钟域,如图21所示。

                                 图21-多循环路径(MCP)方案触发脉冲生成和确认

        对于图21中的示例,确认反馈信号(b_ack)生成一个确认脉冲(aack),该脉冲用作小型READY-BUSY、1-状态FSM块的输入,该块生成一个就绪信号(aready),以指示现在可以安全地再次更改数据输入(adatain)值。一旦aready信号变高,发送器就可以自由发送新数据(adatain)和伴随的asend控制信号。这是一个自动反馈路径,它假设接收时钟域将始终为通过MCP方案同步的下一个数据字做好准备。
5.6.3 Closed-loop - MCP formulation with acknowledge feedback(闭环-具有确认反馈的MCP方案)
        第5.6.2节中描述的技术的一个完全响应的变体使用MCP方案,即只有在接收时钟域用bload脉冲确认接收到数据后,才将使能信号作为确认信号传递回发送时钟域,如图22所示。

                         图22-多循环路径(MCP)方案翻转脉冲生成(带就绪确认)
        对于图22中的示例,接收时钟域有一个小的WAIT-READY,1-状态FSM,当数据寄存器输入上的数据有效时,它会向接收逻辑发送有效信号(bvalid)。直到接收逻辑确认应该通过断言bload信号来加载数据,才实际加载数据。在数据被加载之前,没有对发送时钟域的反馈,然后b_ack信号被发送回与具有自动反馈的MCP方案相同的信号。这是一条反馈路径,在捕获数据和发送反馈之前,需要对接收时钟域的一部分进行操作。
5.7 Synchronizing counters(同步计数器)
        如前所述,当在时钟域之间传递多个信号时,需要问的一个重要问题是,我是否需要对从一个时钟域传递到另一个时钟域的信号的每个值进行采样?对于计数器,答案经常是否定的!
        参考文献[1]详细介绍了FIFO设计技术,其中在时钟域之间对格雷码计数器进行采样,并且经常遗漏中间格雷计数值。对于这种FIFO设计,更需要考虑的是确保计数器不会超出其边界,这可能会导致丢失满和空标志检测。即使时钟域之间的采样格雷计数值经常被遗漏,该设计也是稳健的,并且所有重要的格雷计数值都被适当地采样。有关详细信息,请参见[1]。
        由于有效的设计可能被允许跳过一些计数值样本,那么任何计数器都可以用来跨越CDC边界传递计数值吗?答案是否定的。
5.7.1 Binary counters(二进制计数器)
        二进制计数器的一个特征是,所有顺序二进制递增操作的一半要求两个或多个计数器位必须改变。试图在CDC边界上同步二进制计数器与试图将多个CDC信号同步到新的时钟域中是一样的。如果一个简单的4位二进制计数器从地址7(二进制0111)变为地址8(二进制1000),则所有四个计数器位将同时改变。如果同步时钟边沿位于该转换的中间,则可以对任何4位二进制模式进行采样,并将其同步到新的时钟域中,如图23所示。

                                 图23-转换中期采样的二进制计数值                

        在FIFO设计中,新的同步二进制值(也就是目标时钟域采集到的数据)可能会触发假满或空标志,或者更糟的是,它可能不会触发真正的满或空标记,从而导致数据因FIFO溢出而丢失,或者在FIFO真正为空时,由于试图读取数据而导致从FIFO读取无效数据。
5.7.2格雷码(格雷码)
        格雷码以Frank Gray[4]命名,可用于多时钟设计的最安全计数器是格雷码计数器。格雷码只允许每个时钟转换改变一个比特,从而消除了试图在时钟域上同步多个变化的CDC比特的相关问题。标准格雷码具有非常好的转换特性,可以将格雷码转换为二进制,然后再转换回来。使用这些转换,可以简单地设计高效的格雷码计数器。
5.7.3 Gray-to-binary conversion(格雷码转换为二进制码)
        为了将格雷码值转换为等效的二进制码值,以n位格雷码值为例,二进制位0等于与从1到n的所有其他格雷码位独占的格雷码位0的异或。二进制比特1等于格雷码比特1,与从2到n的所有其他格雷码比特异或,等等。最高有效二进制位恰好等于最高有效格雷码位。样本4位格雷码到二进制转换的方程式如图24所示。

bin[0] = gray[3] ^ gray[2] ^ gray[1] ^ gray[0];
bin[1] = gray[3] ^ gray[2] ^ gray[1];
bin[2] = gray[3] ^ gray[2];
bin[3] = gray[3];

                                        图24-4位灰度到二进制的转换方程
        对格雷码到二进制转换器进行编码的最简单方法是对for循环进行编码,并对具有可变索引范围的格雷码向量进行异或归约,其中每次通过循环,索引范围的LSB都会增加,直到我们只剩下bin[MSB]=^gray[MSB:MSB](仅格雷码向量的1位MSB)的简单赋值,如示例1所示。

module gray2bin_bad #(parameter SIZE = 4)
(output logic [SIZE-1:0] bin,
input logic [SIZE-1:0] gray);
// Syntax Error - variable index range
always_comb
for (int i=0; i<SIZE; i++)
bin[i] = ^(gray[SIZE-1:i]);
endmodule

                                示例1-不工作但概念上正确的格雷码到二进制系统Verilog模型
        不幸的是,Verilog和SystemVerilog不允许使用可变索引范围进行部件选择,因此示例1中的代码虽然在概念上是正确的,但不会编译。
        要解决这个问题,请记住,异或门实际上是一个可编程反相器。如果一个输入为高电平,则另一个输入被反相并传递到输出。类似地,如果一个输入被绑定为低,则另一个输入在没有反转的情况下被传递到输出(从输入到输出没有变化)。利用这样一个事实,即任何添加的异或或涉及0输入的操作都不会改变操作的结果,格雷码到二进制转换的方法是使用填充的0来异或或有效的格雷码位,如图25所示。​​​​​​​

bin[0] = gray[3] ^ gray[2] ^ gray[1] ^ gray[0] ; // gray>>0
bin[1] = 1'b0 ^ gray[3] ^ gray[2] ^ gray[1] ; // gray>>1
bin[2] = 1'b0 ^ 1'b0 ^ gray[3] ^ gray[2] ; // gray>>2
bin[3] = 1'b0 ^ 1'b0 ^ 1'b0 ^ gray[3] ; // gray>>3

                                图25-4位格雷码到二进制转换方程-第二种方法​​​​​​​
        该简化算法的相应参数化SystemVerilog模型如示例2中所示。这个例子在语法上是正确的,可以编译并且确实有效。

module gray2bin #(parameter SIZE = 4)
(output logic [SIZE-1:0] bin,
input logic [SIZE-1:0] gray);
always_comb
for (int i=0; i<SIZE; i++)
bin[i] = ^(gray>>i);
endmodule

                        示例2-参数化和正确的格雷码到二进制SystemVerilog模型​​​​​​​

        输入绑定到0的所有额外的异或操作会发生什么?综合工具认识到,可以优化一个输入上具有常数0的异或门,以推断出设计的非常有效的实现。​​​​​​​
5.7.4 Binary-to-gray conversion(二进制到格雷码的转换)
       
 为了将二进制值转换为等效格雷码值,以n位二进制值为例,格雷码位0等于二进制位0和1的异或。格雷码比特1等于二进制比特1和2的异或,等等。最高有效格雷码位恰好等于最高有效二进制位。样本4位二进制到格雷码转换的方程式如图26所示。

gray[0] = bin[0] ^ bin[1];
gray[1] = bin[1] ^ bin[2];
gray[2] = bin[2] ^ bin[3];
gray[3] = bin[3] ^ 1'b0 ; // same as gray[3] = bin[3];

                                        图26-4位二进制到格雷码转换方程
        对二进制到格雷码转换器进行编码的最简单方法是对简单的连续赋值进行编码,该赋值在二进制矢量和同一二进制矢量的右移版本之间执行逐位异或运算,如示例3所示。这个例子在语法上是正确的,可以编译并且确实有效。

module bin2gray #(parameter SIZE = 4)
(output logic [SIZE-1:0] gray,
input logic [SIZE-1:0] bin);
assign gray = (bin>>1) ^ bin;
endmodule

                        示例3-参数化二进制到格雷码系统Verilog模型​​​​​​​
5.7.5 Gray code counter style #1(格雷码计数器类型#1)
       
 我们可以使用第5.7.3节和第5.7.4节中所示的转换来构建格雷码计数器。对于任何格雷码计数器,重要的是要记住,必须注册灰度输出,以消除设计中的任何组合沉降。用于格雷码计数器样式#1的SystemVerilog代码包含一个灰度到二进制转换器、一个二进制到灰度转换器,并在转换之间增加二进制值,如图27所示。

                        图27-1型格雷码计数器-只有一个格雷码寄存器​​​​​​​
                示例4中示出了用于格雷码计数器样式#1的相应参数化SystemVerilog模型。​​​​​​​

module graycntr #(parameter SIZE = 5)
(output logic [SIZE-1:0] gray,
input logic clk, inc, rst_n);
logic [SIZE-1:0] gnext, bnext, bin;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) gray <= '0;
else gray <= gnext;
always_comb begin
for (int i=0; i<SIZE; i++)
bin[i] = ^(gray>>i);
bnext = bin + inc;
gnext = (bnext>>1) ^ bnext;
end
endmodule

                                示例4-参数化格雷码计数器SystemVerilog模型​​​​​​​
5.7.6 Gray code counter style #2(格雷码计数器类型#2)
        我们可以通过使用第5.7.4节中所示的二进制到格雷码的转换来构建第二种类型的格雷码计数器。这个格雷码计数器实际上既是二进制计数寄存器又是格雷码计数寄存器。​​​​​​​

                        图28-格雷码计数器类型#2-二进制寄存器和格雷码寄存器​​​​​​​
        用于格雷码计数器样式#2的SystemVerilog代码包含一个二进制计数器,以消除灰度到二进制转换的需要,并使用下一个二进制计数值进行二进制到灰度转换,然后将其寄存到格雷码寄存器中。这种类型使用两倍多的触发器,但使用更短的组合逻辑路径来生成下一个格雷码值,这使得这种实现比格雷码计数器类型#1更快。
        2型格雷码计数器的框图如图28所示,示例5中示出了用于格雷码计数器样式#2的相应参数化SystemVerilog模型。

module graycntr #(parameter SIZE = 5)
(output logic [SIZE-1:0] gray,
input logic clk, full, inc, rst_n);
logic [SIZE-1:0] gnext, bnext, bin;
always_ff @(posedge clk or negedge rst_n)
if (!wrst_n) {bin, gray} <= '0;
else {bin, gray} <= {bnext, gnext};
assign bnext = !full ? bin + inc : bin;
assign gnext = (bnext>>1) ^ bnext;
endmodule

                                        示例5-带二进制计数器的参数化格雷码计数器​​​​​​​
5.8 Additional multi-bit CDC techniques(额外的多位CDC技术)
        除了前面章节中描述的MCP方案技术之外,我发现许多工程师使用标准FIFO在时钟域之间传递数据和控制信号。至少有两种有趣的FIFO实现策略可用于解决多位CDC信号完整性问题:
(1) 异步FIFO实现
(2) 2-deepFIFO实现
5.8.1 Multi-bit CDC signal passing using asynchronous FIFOS(使用异步FIFOS传递多位CDC信号)
        传递多个比特,无论是数据比特还是控制比特,都可以通过异步FIFO来完成。异步FIFO是一种共享存储器或寄存器缓冲区,其中数据从写入时钟域插入,数据从读取时钟域移除。由于发送器和接收器都在各自的时钟域内工作,因此使用双端口缓冲器(如FIFO)是在时钟域之间传递多位值的安全方式。
        只要FIFO未满,标准异步FIFO设备就允许插入多个数据或控制字,并且只要FIFO未空,接收器就可以在方便时提取多个数据和控制字。
        FIFO设计中的大部分艰苦工作都是通过格雷码计数器的同步来完成的,[1]中描述了一种行之有效的FIFO设计技术。
5.8.2 Multi-bit CDC signal passing using 1-deep / 2-register FIFO synchronizer(使用1-deep/2寄存器FIFO同步器传递多位CDC信号)
        跨CDC边界传递多个控制和数据位的另一个有趣的变化涉及使用一个1-deep两寄存器FIFO,如图29所示。

                                                 图29-1-deep/2寄存器FIFO同步器框图

        这种一级双寄存器FIFO具有许多有趣的特性。由于FIFO只使用两个寄存器或一个2深双端口RAM构建,用于检测满和空的格雷码计数器是简单的触发器,实际上只不过是1位二进制计数器
(请记住,标准格雷码的最高有效位与二进制码的最高最高有效位相同)。
        复位时,两个指针都被清除,FIFO为空,因此FIFO未满。我们使用反相未满条件来指示FIFO已准备好接收数据或控制字(wrdy为高)。在数据或控制字被放入FIFO(使用wput)后,wptr翻转,FIFO变满,或者换句话说,wrdy信号变低,这也禁用了翻转wptr的能力,因此也禁用了将另一个字放入2寄存器FIFO的能力,直到接收时钟域逻辑从FIFO中移除第一个字。
        这种设计特别有趣的是,wptr现在指向2寄存器FIFO中的第二个位置,因此当FIFO再次准备就绪时(当wrdy为高时),wptr已经指向下一个要写入的位置。
        在FIFO的接收端复制了相同的概念。当数据或控制字被写入FIFO时,FIFO不会变为空。我们使用反相非空条件来指示FIFO具有准备好接收的数据或控制字(rrdy为高)。
        通过使用两个寄存器来存储多位CDC值,我们能够从发送MCP方案中去除一个时钟周期,从确认反馈路径中去除另一个周期。
​​​​​​​

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值