跨时钟域问题(Clock Domain Crossing)

合集下载

跨时钟域的方法

跨时钟域的方法

跨时钟域的方法
跨时钟域的方法,是指在两个或多个时钟之间进行同步的一种技术。

在现代通信和计算机网络中,不同设备的时钟往往有微小的差异,如果不进行同步,就可能导致通信中的时间戳错误或者计算机网络中的数据同步问题。

因此,跨时钟域的方法是保证不同设备之间时间同步的关键技术之一。

在实际应用中,跨时钟域的方法主要包括两种:硬件同步和软件同步。

硬件同步是指使用专门的硬件设备来进行时钟同步,例如使用GPS信号来同步时钟;软件同步则是指使用特定的软件算法来进行时钟同步,例如使用NTP协议来进行网络时间同步。

这两种方法各有优缺点,在具体应用中需要根据实际需求来选择合适的方法。

在跨时钟域的方法中,还需要考虑到时钟漂移和时钟抖动等问题。

时钟漂移指的是时钟频率的变化,而时钟抖动则是指时钟频率的波动。

这些问题会影响时钟同步的精度,因此需要采取相应的措施来进行补偿。

在硬件同步中,一般采用精密的晶振来提高时钟精度;在软件同步中,采用算法来进行时钟漂移和抖动的补偿。

总之,跨时钟域的方法是现代通信和计算机网络中非常重要的技术之一。

它可以保证不同设备之间的时间同步,从而确保通信和数据同步的准确性和可靠性。

在实际应用中,需要根据具体情况选择合适的同步方法,并且采取相应的措施来解决时钟漂移和抖动等问题。

快时钟到慢时钟跨时钟域处理

快时钟到慢时钟跨时钟域处理

快时钟到慢时钟跨时钟域处理随着现代电子技术的不断发展,各种智能设备越来越普及,而这些设备中都包含了各种不同的时钟。

面对不同的时钟,如何进行跨时钟域处理成为了一个重要的问题。

本文将围绕这个问题展开讨论。

一、时钟域时钟域是指在一个系统中,由于时钟信号的不同而形成的不同的时钟区域。

在一个系统中,可能会有多个时钟域,每个时钟域都由一个时钟信号驱动。

例如,一个处理器的时钟域和一个外设的时钟域就是两个不同的时钟域。

二、时钟域的跨越在一个系统中,不同的时钟域之间需要进行数据的传输和交互。

但是,由于不同的时钟域具有不同的时钟频率和时钟相位,因此在传输和交互数据时会遇到一些问题。

例如,如果一个时钟域的时钟频率是100MHz,而另一个时钟域的时钟频率是50MHz,那么在传输数据时就需要进行频率的转换。

又例如,如果一个时钟域的时钟相位发生了变化,那么在传输数据时就需要进行时钟相位的校准。

三、跨时钟域处理的方法为了解决跨时钟域处理的问题,有以下几种方法。

1.同步方法同步方法是指在不同的时钟域之间建立同步信号,使得数据能够在同步信号的边沿进行传输。

这种方法需要在两个时钟域之间建立同步电路,并且需要在同步电路中添加缓存器来保证数据的正确传输。

同步方法的优点是能够保证数据的正确性,缺点是需要额外的硬件开销。

2.异步方法异步方法是指在不同的时钟域之间使用异步传输协议进行数据的传输。

这种方法不需要建立同步电路,只需要使用异步传输协议即可。

异步方法的优点是不需要额外的硬件开销,缺点是在数据传输过程中可能会出现误码。

3.频率转换方法频率转换方法是指将一个时钟域的时钟频率转换成另一个时钟域的时钟频率。

这种方法需要使用时钟控制电路来实现,可以通过倍频或分频的方式实现。

频率转换方法的优点是不需要建立同步电路,缺点是会引入一定的时钟抖动。

4.时钟域转换方法时钟域转换方法是指将一个时钟域的时钟信号转换成另一个时钟域的时钟信号。

这种方法需要使用时钟域转换电路来实现。

FPGA_跨时钟域介绍

FPGA_跨时钟域介绍

跨时钟域4.1跨时钟域处理(20160620)时钟对于FPGA就像我们的心脏,时刻控制着“跳动”的频率以及“血液”的流速;时钟域好比通过心脏的血液血型,不同血型的血液会产生排斥作用。

在设计中建议时钟越少越好,好比于人有两个甚至更多的心脏,其内脏工作将会多么混乱。

但是某些情况下多时钟又不可避免,比如从FPGA外部输入的数据,其自带有个随路时钟,数据终归要在FPGA内部时钟域下处理,这来自外部的“血液”如何处理才能与内部的“血液”融合呢?配对及转换工作则是必不可少的,这就引入本节的主题:跨时钟域处理(Clock Domain Crossing):跨时钟域处理需要两方面的工作:1、设计者处理;2、FPGA工具(Vivado)处理。

1.设计者处理首先讲解一下如果不进行跨时钟域处理,会出现什么问题呢?如图1所示路径,QA属于CLKA时钟域的数据输出,另一个时钟CLKB去捕获节点REG A 的输出QA,假定CLKA与CLKB是异步时钟,它们之间的相位并不固定,因此捕获过程中可能会出现建立冲突(setup violation)和保持冲突(hold violation),如图2所示,左右分别为发生建立冲突和保持冲突的情况。

图1图2当冲突出现时(我感觉整个人都不好了),会发生什么事情呢?在发生建立冲突或者保持冲突,捕获节点(REG B)会处于一个不定的状态,正常的状态是高电平或者低电平,而此时的状态停留在高电平和低电平的中间,无效的电平X,称这个状态为亚稳态。

如图3所示,捕获节点输出保持在亚稳态,可能在整个时钟周期内都保持在亚稳态,由于不正确的状态,其后连接的逻辑在功能实现上就会出现问题,比如一个判断信号上升沿的逻辑,通常判断D==HIGH&&D_PREV==LOW(D为信号当前电平状态,D_PREV为信号上个时钟的电平状态)是否成立,而发生亚稳态时则D_PREV==X,这个上升沿将会错过。

因此,加入跨时钟域处理设计是必须的。

跨时钟域的设计

跨时钟域的设计

跨时钟域的设计参考⾃part 1.跨时钟域的信号如果时钟域B需要使⽤来⾃时钟域A的信号,那么需要对这个信号进⾏同步。

如果输⼊信号⽐起时钟B来讲变化较慢,可以使⽤两个触发器来完成1: module Signal_CrossDomain(2: input clkA, // we actually don't need clkA in that example, but it is here for completeness as we'll need it in further examples 3: input SignalIn_clkA,4: input clkB,5: output SignalOut_clkB6: );7:8: // We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain9: reg [1:0] SyncA_clkB;10: always @(posedge clkB) SyncA_clkB[0] <= SignalIn_clkA; // notice that we use clkB11: always @(posedge clkB) SyncA_clkB[1] <= SyncA_clkB[0]; // notice that we use clkB12:13: assign SignalOut_clkB = SyncA_clkB[1]; // new signal synchronized to (=ready to be used in) clkB domain14: endmodulepart 2 跨时钟的Flag当信号是⼀个短脉冲时1: module Flag_CrossDomain(2: input clkA,3: input FlagIn_clkA,4: input clkB,5: output FlagOut_clkB6: );7:8: // this changes level when the FlagIn_clkA is seen in clkA9: reg FlagToggle_clkA;10: always @(posedge clkA) FlagToggle_clkA <= FlagToggle_clkA ^ FlagIn_clkA;11:12: // which can then be sync-ed to clkB13: reg [2:0] SyncA_clkB;14: always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA};15:16: // and recreate the flag in clkB17: assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]);18: endmodule1: module FlagAck_CrossDomain(2: input clkA,3: input FlagIn_clkA,4: output Busy_clkA,5: input clkB,6: output FlagOut_clkB7: );8:9: reg FlagToggle_clkA;10: always @(posedge clkA) FlagToggle_clkA <= FlagToggle_clkA ^ (FlagIn_clkA & ~Busy_clkA);11:12: reg [2:0] SyncA_clkB;13: always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA};14:15: reg [1:0] SyncB_clkA;16: always @(posedge clkA) SyncB_clkA <= {SyncB_clkA[0], SyncA_clkB[2]};17:18: assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]);19: assign Busy_clkA = FlagToggle_clkA ^ SyncB_clkA[1];20: endmodulepart3 task1: module TaskAck_CrossDomain(2: input clkA,3: input TaskStart_clkA,4: output TaskBusy_clkA, TaskDone_clkA,5:6: input clkB,7: output TaskStart_clkB, TaskBusy_clkB,8: input TaskDone_clkB9: );10:11: reg FlagToggle_clkA, FlagToggle_clkB, Busyhold_clkB;12: reg [2:0] SyncA_clkB, SyncB_clkA;13:14: always @(posedge clkA) FlagToggle_clkA <= FlagToggle_clkA ^ (TaskStart_clkA & ~TaskBusy_clkA);15:16: always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA};17: assign TaskStart_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]);18: assign TaskBusy_clkB = TaskStart_clkB | Busyhold_clkB;19: always @(posedge clkB) Busyhold_clkB <= ~TaskDone_clkB & TaskBusy_clkB;20: always @(posedge clkB) if(TaskBusy_clkB & TaskDone_clkB) FlagToggle_clkB <= FlagToggle_clkA;21:22: always @(posedge clkA) SyncB_clkA <= {SyncB_clkA[1:0], FlagToggle_clkB};23: assign TaskBusy_clkA = FlagToggle_clkA ^ SyncB_clkA[2];24: assign TaskDone_clkA = SyncB_clkA[2] ^ SyncB_clkA[1];25: endmoduleTo move a data bus (2 bits wide or more) from one clock domain to another, we have several techniques to our disposal.Here are a few ideas.Gray code: If the data bus is a monotonic counter (i.e. only incrementing or decrementing), we can convert it to a , which has the ability to cross clock domains (under certain timing conditions).Data freeze: If the data bus is non-monotonic, use a to signal the other domain to capture the value (while it is frozen in the source clock domain).Data burst: If the data bus has many consecutive values that need to cross the clock domain, use an , where you push values from the source clock domain, and read back values from the other domain.That's all folks!。

跨时钟域处理方法

跨时钟域处理方法

跨时钟域处理方法跨时钟域处理(Cross-ClockDomainProcessing)也被称为跨时钟域通信(CCDC),是一种在不同的时钟芯片或部件间实现通信的方法。

它可以帮助企业减少制造时间,降低成本,提高性能和灵活性,并允许更快地向市场投入新产品。

跨时钟域处理技术可以减少能耗,更有效地为更多的应用程序和处理任务提供高效的解决方案。

它还能减少误码和数据传输失败的可能性,提高系统的可靠性。

跨时钟域处理可以用来支持不同的芯片,例如处理器,存储器,收发器,传感器和控制器,以及他们之间的交互。

在某些情况下,它还可以用来将外部固件与主CPU和内部芯片相结合,以便在主CPU芯片和外部芯片之间传输数据,从而形成更复杂的系统集成解决方案。

跨时钟域处理可以采用端口技术来使不同频率的时钟芯片能够正常工作。

每个芯片都有一个专用端口,它可以产生和接受数据,而不受另一个芯片的时钟频率的限制。

例如,如果一个芯片使用的是200MHz的时钟,而另一个芯片使用的是2GHz的时钟,那么使用端口就可以让这两个芯片能够正常工作,而不用担心后者会干扰前者的时钟。

另一种常用的跨时钟域处理技术是串行总线技术。

它允许多个晶体管和元件在共享的串行总线上通信,而无需考虑他们之间的时钟频率和时差。

这种技术允许用户更容易地访问和控制每个芯片的信号,而无需考虑时钟延时的问题。

最后,要注意的是,跨时钟域处理技术的实施必须保证其精确性和可靠性。

这可能会需要使用适当的补偿和专用控制系统,以确保系统中的所有芯片能够正常工作并保持稳定性,从而实现最佳性能和可靠性。

总之,跨时钟域处理是一种令人印象深刻的技术,可以有效地减少成本,并提高系统性能,提高可靠性和性能。

此外,它还可以帮助更快地推向市场新产品,提高市场竞争力。

企业应该利用跨时钟域处理技术,以更有效的方式来解决问题,实现更多的目标。

CDC跨时钟域处理

CDC跨时钟域处理

单信号:慢时钟域快时钟域
• 如果我们仍然使用同样的参数,则第2级触发器 的MTBF为9.57 *10^9(years) 。这个值已经足以 使系统长期稳定。
总结
• 问题1:为何直接对异步信号进行采样会不稳 定? • 问题2:要使用几级寄存器进行同步最合适? • 问题3:同步寄存器电路可以防止亚稳态产生 吗?
单信号:快时钟域慢时钟域
• 当快时钟域的信号跳变太快,导致目标时 钟域无法采样时,应如何处理? • 1.拉伸快时钟域信号的脉冲宽度使其足以被 正确采样 • 2.结绳法(脉冲同步器)
① 脉冲拉伸法
脉冲拉伸同步电路
② 结绳法 • 信号从快时钟域向慢时钟域过渡时,慢时钟 将可能无法对变化太快的信号实现正确采样。
• “结绳法”原理:将快时钟信号的脉冲周期 延长,等到慢时钟同步采样后再“解绳”还 原为原来的脉冲周期宽度。
单信号:快时钟域慢时钟域 结绳同步电路
Synopsys DW库内的推荐电路
脉冲同步器使用规则 • 1. 总线数据不能对每个信号单独使用同步 器,会导致数据无法同时有效。 • 2.输入的信号必须是单周期脉宽,否则无法 成功进行“结绳”操作 • 3.输入脉冲之间的最小间隔必须等于两个同 步器时钟周期。如果输入脉冲相邻太近, 则同步器就不能检测到每个脉冲。
主要内容
• • • • 1.单一信号跨时钟域处理 2.总线数据的跨时钟域处理 3.数据流的跨时钟域处理 4.相关时钟系统数据同步
相关时钟系统
• 如果两个时钟分别为同一个源时钟的分频或倍 频时钟,则称为相关时钟 • 相关时钟的相位是可以通过工具进行对齐的 • 跨越的时钟域为相关时钟,这时可以用更简便 的处理方式,简化同步电路
工艺器件映射
• 在DC将两个触发器映射到一个目标库上时,综 合工具会选择能够满足时序限制条件的最小面 积的单元,而不是对同步最好的触发器 • 因此通常想要通过手动方式或通过脚本方式用 已知的“亚稳态强化”触发器来替代这些触发 器 • 自DC2009版本开始,可以指定一个或多个“亚 稳态强化”触发器用在上述DW库中的CDC组件。 • 方法:通过将相关器件赋给 “synlib_preferred_ffs”变量实现特定寄存器的 调用

快时钟到慢时钟跨时钟域verilog处理

快时钟到慢时钟跨时钟域verilog处理

快时钟到慢时钟跨时钟域verilog处理一、前言时钟在数字电路中扮演着至关重要的角色,它是同步电路的基础。

而时钟域则是指在不同的时钟频率下,电路中的寄存器和逻辑单元所处的不同时钟区域。

跨越不同时钟域的数据传输需要进行特殊处理,否则会导致数据错误。

本文将介绍如何使用Verilog语言处理快时钟到慢时钟跨时钟域问题。

二、什么是时钟域1. 时钟在数字电路中,为了保证各个模块之间能够协调工作而不会发生冲突,需要引入一个基准信号来进行同步。

这个基准信号就是我们常说的“时钟”。

2. 时钟域由于数字电路中可能存在多个时钟信号,每个时钟信号都有自己的频率和相位。

因此,在数字电路中会形成多个互相独立的“时间区域”,也就是我们所说的“时钟域”。

三、快慢时钟之间数据传输问题当两个模块处于不同的时钟域中,并且这两个模块需要进行数据传输或共享一个寄存器/内存单元等操作,就会出现跨越不同时间区域(时钟域)的数据传输问题。

在不同的时钟域之间进行数据传输,需要考虑以下问题:1. 时序关系由于不同的时钟信号具有不同的频率和相位,因此在进行跨时钟域数据传输时,需要考虑这两个模块之间的时序关系。

通常情况下,我们会使用一些特殊技术来解决这个问题,例如手动插入缓冲器或者FIFO 等。

2. 数据同步由于不同的时钟信号具有不同的频率和相位,因此在进行跨时钟域数据传输时,可能会出现数据丢失、错误或者抖动等问题。

为了解决这个问题,我们通常会使用一些特殊技术来进行数据同步。

例如手动插入缓冲器、FIFO、双缓存技术等。

四、Verilog语言如何处理跨越不同时钟域的问题在Verilog语言中,我们可以使用$setup()和$hold()函数来解决跨越不同时间区域(时钟域)的数据传输问题。

1. $setup()$setup()函数用于检查从一个寄存器到另一个寄存器之间是否存在时间上危险(setup time violation)。

如果存在,则该函数返回1;否则返回0。

FPGA_跨时钟域

FPGA_跨时钟域

跨时钟域4.1跨时钟域处理(20160620)时钟对于FPGA就像我们的心脏,时刻控制着“跳动”的频率以及“血液”的流速;时钟域好比通过心脏的血液血型,不同血型的血液会产生排斥作用。

在设计中建议时钟越少越好,好比于人有两个甚至更多的心脏,其内脏工作将会多么混乱。

但是某些情况下多时钟又不可避免,比如从FPGA外部输入的数据,其自带有个随路时钟,数据终归要在FPGA内部时钟域下处理,这来自外部的“血液”如何处理才能与内部的“血液”融合呢?配对及转换工作则是必不可少的,这就引入本节的主题:跨时钟域处理(Clock Domain Crossing):跨时钟域处理需要两方面的工作:1、设计者处理;2、FPGA工具(Vivado)处理。

1.设计者处理首先讲解一下如果不进行跨时钟域处理,会出现什么问题呢?如图1所示路径,QA属于CLKA时钟域的数据输出,另一个时钟CLKB去捕获节点REG A 的输出QA,假定CLKA与CLKB是异步时钟,它们之间的相位并不固定,因此捕获过程中可能会出现建立冲突(setup violation)和保持冲突(hold violation),如图2所示,左右分别为发生建立冲突和保持冲突的情况。

图1图2当冲突出现时(我感觉整个人都不好了),会发生什么事情呢?在发生建立冲突或者保持冲突,捕获节点(REG B)会处于一个不定的状态,正常的状态是高电平或者低电平,而此时的状态停留在高电平和低电平的中间,无效的电平X,称这个状态为亚稳态。

如图3所示,捕获节点输出保持在亚稳态,可能在整个时钟周期内都保持在亚稳态,由于不正确的状态,其后连接的逻辑在功能实现上就会出现问题,比如一个判断信号上升沿的逻辑,通常判断D==HIGH&&D_PREV==LOW(D为信号当前电平状态,D_PREV为信号上个时钟的电平状态)是否成立,而发生亚稳态时则D_PREV==X,这个上升沿将会错过。

因此,加入跨时钟域处理设计是必须的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

跨时钟域问题(Clock Domain Crossing) –同两个时钟域打交道!
引言:设计者有时候需要将处于两个不同时钟域的系统对接,由于接口处是异步(会产生setuptime 和holdtime violation,亚稳态以及不可靠的数据传输)的,因此处理起来较同步逻辑更棘手,需要寻求特殊处理来进行接口界面的设计。

任意的两个系统如果满足以下条件之一,就可称其为异步的:
(1)工作在不同的时钟频率上;
(2)工作频率相同,但是相位不相同;
处理跨时钟域的数据传输,有两种实现方案:
(1)采用握手信号来交互
(2)以异步FIFO来实现
1.1、以握手信号交互:
假设系统A以这种方式向系统B传递数据,握手信号分别为req和ack。

握手协议:
Transmitter asserts the req (request) signal, asking the receiver to accept the data on the data bus.
Receiver asserts the ack (acknowledge) signal, asserting that it has accepted the data.
这种处理跨时钟域的方式很直接,但是也最容易产生亚稳态,由于系统A发送的req信号需要系统B中的时钟去sample,而系统B发出的ack信号又需要系统A中的时钟去sample,这样两边都存在着setup time和hold time violation的问题。

为了避免由于setup time和hold time vilation所造成的亚稳态,通常我们可以将异步时钟域交互的信号用local system的时钟打两级甚至三级寄存器,以此来消除亚稳态的影响。

下图以系统A发送到系统B的req信号示例消除亚稳态的方法:
当然,这种处理方式是以损失传输速率为代价的,加入两到三级寄存器同步异步时钟域的信号,会有许多时钟周期浪费在了系统的“握手”。

有时候,我们也会对数据多打两拍reg来同步,但通常情况下,我们并不会采取这种方式,它不仅需要较多逻辑,而且收效甚微。

通常对数据的同步是以异步FIFO来实现的。

下图给出了1bit数据传输打两拍reg所做的同步,从中可以发现,与前面的握手信号处理完全一致。

1.2 结合实际工作谈谈以握手信号处理的跨时钟域问题
由于所在项目的逻辑设计相当庞大,超出了最初的预估,同时也鉴于产品化方向考虑可以单独流片,因此对整个逻辑结构进行了划分,在做FPGA原型验证的时候,将这两块逻辑分别映射到不同的器件单元中,这里暂且称它们为wrapper0和wrapper1。

实践结果表明,wrapper0和wrapper1的相位需要存在180度的反相,弥补板级走线的延迟影响。

这样一来,在wrapper0和wrapper1主交互界面的信号就横跨时钟域,存在着亚稳态问题的困扰了。

由于个人对此处亚稳态问题的认识程度不充分,当时没有对界面上的信号做处理,而是将精力放在了对pin脚延迟的处理上,结果收效甚微。

设计的功能是视频编码相关的,测试的结果就会发现:一开始,经过前处理的数据写入到SDRAM内部也是正常的,编码出来的图像经过AP(Application Program)实时播放显示也是正常的,而且有早期测试的基础放在那里,显然不可能是编码内核本身出了差错;在间隔一段时间后,可以明显看到AP实时播放的图像出现了绿色的竖状条,而且随着时间的累积,这些竖条会逐步扩展,移动。

这种现象很明显地告诉设计人员:前处理后的数据与SDRAM通信时存在着bug!
SDRAM controller模块,或者说总线仲裁模块(我们的设计并不是采用SOC 方案,而是以纯ASIC的方案进行,总线仲裁和流水线调度都放在了SDRAM controller中)的问题排查是比较好解决的。

一来,该模块中集成了SDRAM 自测试逻辑,可以很方便地检测对SDRAM的读写是否存在着误差;二来,编码内核本身从SDRAM取数据也进行了旁路设计,就是说编码的数据可以是以测试模式来处理,而并非实际外接的数据源,这样就可以在长时间编码时查看AP是否同样会出现上述症况。

在本人和项目组其他同仁以上述方案进行了探索性测试后,确定了前面所述的结论:问题的根源肯定不是发现在编码内核,而是前处理后的数据与SDRAM 通信时存在着bug!但,令人沮丧的是,我们走了一条错误的道路,认为问题的根源在于板级延迟造成的,而不是跨时钟域的问题,直到走到死胡同里才发现:哟,原来刚才那条小道才是出路!
实践也确实检验了处理亚稳态的理论:wrapper0和wrapper1的交互信号在做了两级寄存器同步后,整个系统安全稳定的运行!
所以说,看本文的各位同仁,千万要记得在处理跨时钟域问题时多留神,不要被这个看似不大不小的问题折腾得食不甘味、夜不能寐啊,哈哈,有些小夸张
2.1 以异步FIFO应对跨时钟域设计
对性能要求较高而不太计较资源,或者不期望浪费时间在握手信号的处理上时,通常会采用异步FIFO来处理跨时钟域可能引入的亚稳态问题。

异步FIFO的两个界面分别完成数据的写入和读取,两个界面的时钟是不一致的(当然,如果一致的话也就无从谈异步FIFO了)。

这里假设系统A向异步FIFO写入数据,系统B从异步FIFO中读取数据。

为了对可能引入的错误操作进行处理(例如,没有空间了,却还有数据要写入,或者是相反,完全腾空了,却有读取数据的操作),我们引入了FIFO空、满(empty, full)信号,这两个信号都是产生于相对应的时钟域,也就是说,这两个信号是处在不同的时钟域当中的!例如:FIFO full信号由系统A产生(当FIFO写满时,我们不期望系统A有数据要写入,否则,会发生数据丢失),或者说该信号是有写入时钟驱动的;类似地,FIFO empty信号受读取时钟驱动(当FIFO读空时,我们也不期望系统B有读数据的请求,否则,会读取错误的数据)。

如何设计异步FIFO不是本文所要探讨的问题,不过我希望提醒大家的是:对FIFO空、满信号的处理一定要多加注意,上面以及提到,这两者是处于不同时钟域中的,会造成亚稳态问题。

2.2 结合实际工作谈谈以异步FIFO处理的跨时钟域问题
无论是做数据通信、音视频处理、图形图像,还是做网络安全、数据存储,都无法避开的问题就是和各种各样的数据总线协议打交道。

通常来讲,我们的设计不可能碰巧刚刚好和总线协议的时钟同时钟域,或者总线协议支持多种时钟域驱动,因此一来,对数据的传输通道而言,始终都无法避开的一个问题就是:跨时钟域数据交互!
以异步FIFO来处理跨时钟域的数据传输是通用的解决手段,需要特别注意的则是对FIFO空、满信号的处理。

拿所设计的项目中一条传输通路为例,其数据写入是从SDRAM中吐出的,其数据读取符合某一种总线协议,其时钟频率与内核不一致。

这样对于写入端而言,需要对FIFO空信号进行如下处理:
首先,在SDRAM中没有数据时,不要发送要数据的请求;
其次,保证FIFO的深度适当,使得发出FIFO空信号时,SDRAM中不会发生数据覆盖现象;
对于取数据端而言,类似地,需要对FIFO满信号进行如下处理:
首先,保证FIFO满信号能够尽量有规律地发出,保证传输通道以及上层处理程序能够有效响应;
其次,对FIFO满信号(实际处理时的中断信号正是由此信号再作处理得来)以及每次传输得包大小能够调节,保证数据传输得稳定性;
简单来讲,FIFO空了,就有要数据的权利;FIFO满了,就有吐数据的权利;但是,在处理这种空、满信号时又需要考虑周全,什么样的情形下,即使时饿了也不能立刻给吃的;什么样的情形下,即使是饱了也不能立刻离席!而且这个筵席是两方当事人所摆设的,要顾全双方的感受!
打了上述这个小小的比方,不知道是否得当,大家看时权且一笑而过,心领神会就可~~
P.S.:其实,在逻辑设计中,跨时钟域、亚稳态影响正越来越凸现,我们的设计日益复杂,需要交互的接口繁多,如何提高设计的可靠性,保证数据传输以及信号交互的稳定,将是一个重要的设计议题。

本文抛砖引玉,希望有更多高手予以探讨!此外,本人不才,准备将收集到的一些有关跨时钟域的问题整理好、翻译好后与大家一同分享。

相关文档
最新文档