跨时钟域设计问题与方法
- 格式:pdf
- 大小:327.68 KB
- 文档页数:14
浅谈XLINX FPGA设计中跨时钟域的同步设计问题摘要本文介绍了FPGA设计中的同步设计原则并对FPG A设计中的触发器亚稳态问题进行了阐述本文通过具体的设计实例论证了跨时钟域同步处理的必要性并介绍了一种实现跨时钟域同步处理的方法和其具体电路关键字同步设计异步设计触发器亚稳态时序稳定一同步设计的原则尽量使用同步电路避免使用异步电路这句话是电路设计的几个原则之一同异步设计相比同步设计设计出来的电路更稳定可靠在XILINX FPGA设计中时常有设计人员遇到如下类似的问题设计的电路升级困难可移植性差也就是说一些原本工作正常的电路移植到高端的FPGA中就根本工作不起来了设计的电路一致性差同一电路设计每次布线后工作的结果不同设计的电路时序仿真正常但实际电路上却工作不起来设计的电路极易受毛刺的干扰通常这些类似的问题都于电路的异步设计有关二亚稳态图1 触发器的亚稳态示意图对于触发器当时钟沿到来时其输入要求是稳定的这时其输出也是稳定的但假如时钟沿到来时其输入也正在变化即翻转这时触发器会瞬时进入亚稳态通常触发器对输入信号都有一个建立时间的要求也即setup时间当这一建立时间得不到满足时触发器也会进入瞬时亚稳态如图1通常触发器即使进入亚稳态也会很快进入稳态但其输出值是不定的这有可能对使我们设计的FPGA模块尤其是哪些有复杂状态机的模块产生错误的逻辑对于亚稳态问题我们还应明白亚稳态问题并非指输出结果数据的不确定性而是指输出变化的时序不确定性遵循同步设计的原则有助于解决亚稳态问题使我们设计出稳定可靠的电路模块对于单时钟系统我们可以很方便地设计出稳定易于设计及仿真的同步单一时钟系统但在电信和数据通讯领域中我们设计的系统中往往具有多个时钟往往需要将数据或时序由一个时钟域传到另一个时钟域这类设计的难点在于实现不同时钟域之间数据和时序变化的稳定可靠地传递采用经验证的设计技术可以实现跨时钟域的同步设计进而设计出可靠工作的电路三跨时钟域的异步设计案例本人曾经设计过如下几个模块这些模块中的几个子模块分别工作在各自的时钟域中但在他们之间有着数据和时序的传递在设计这些模块的初始时并没有考虑到跨时钟域时序和数据传递的特殊性使得在系统上使用这些模块时出现过一些较为棘手的问题现把它们列举出来供大家研究模块一名称:芯片配置模块模块功能从平行口接收从PC 机下传的命令和参数产生相应的控制时序完成单板上芯片的配置模块结构框图图2 同步处理前芯片配置模块结构框图各子模块简介模块A 实现同PC 的平行接口PC 机控制程序通过操作并行口各个引脚把各个参数信息如数据地址信息传递到参数控制总线上并且发出相应的命令如start, write 等命令启动下层模块模块B 是一个状态机clk 是状态机的主时钟模块B 根据模块A 传来的命令启动相应的状态机完成从参数传递总线上获取参数信息或产生相应的配置时序完成芯片的正确配置在上图中模块A 中各寄存器都受控于并行口各引脚的状态它们在并行口引脚中stroble 引脚的上跳沿发生状态的迁移可以说stroble 引脚是模块A 的主时钟信号由上分析得模块A 和模块B 分属于两不同的时钟域时钟域A 和时钟域B中时钟域A 的主时钟为stroble, 时钟域B 的主时钟为clk 两时钟域的主时钟stroble 和clk 是不相关的它们之间的信号就为跨时钟域A 和时钟域B 之间的信号线其中write 信号线,start 信号线及回馈握手信号线用于实现控制时序的传递而参数传递总线用于实现数据的传递在如上的设计中没有对跨时钟域的时序控制线进行同步处理在系统使用此模块时出现如下的问题Parrel port with PCPC机上芯片配置命令并不能总是成功的启动模块B 中相应的状态机也即PC机上芯片配置命令并不能总是成功地实现芯片的正确配置芯片配置时序的不稳定性故障的偶然性故障的不可重复性模块二名称:突发调制器模块模块功能完成数据的突发调制模块结构框图图3 同步处理前突发调制器模块框图各子模块简介模块A 为突发调制器主控模块它的主时钟为CLKA它利用CLKA定时产生周期的Send_data信号去启动模块B中的状态机模块B为突发调制器时序控制模块它的主时钟是从专用调制器芯片送来的TXBITCLK时钟信号模块B根据模块A的触发信号启动相应的状态机产生相应的调制器控制时序专用调制芯片中的DPLL(数字锁相环)根据相应的设置参数以CLKB为参考时钟产生TXBITCLK时钟信号上图中R1R2为跳接电阻通过R1R2不同的焊剂方式可以改变CLKB时钟信号的时钟源在如上的设计中没有对跨时钟域的时序控制进行同步处理在系统使用此模块时出现如下的问题在R1短接R2断开情况下CLKA时钟信号和CLKB时钟信号共用一个时钟源晶体A,上述模块工作正常稳定在R1断开R2短接情况下CLKA 时钟信号的时钟源为晶体A CLKB 时钟信号的时钟源为晶体B 晶体A 和B 是两个独立不相关的晶体这时模块A 和模块B 工作于不同的时钟域(时钟域A 和时钟域B) 它们之间的信号就为跨时钟域A 和时钟域B 之间的信号线Send_data 信号和回馈握手信号线用于实现两时钟域之间控制时序的传递此时上述模块工作很不稳定模块B 中的状态机经常进入一种未知状态不能产生正确的调制器控制时序四 跨时钟域的同步设计的方法经对上述案例仔细地仿真和深入分析后笔者发现作成上述两模块工作不稳定的主要原因是没有按照同步设计的原则对跨时钟域的时序控制信号进行同步处理可以有好几种电路用于实现跨时钟域的时序控制信号的同步处理下面的电路模块Asy_syc 可以用于跨时钟域时序控制信号的同步处理Asy_inSyc_clkSyc_outTime periphery图4 Asy_syc 电路原理图上述电路的时序仿真图如下:图5 Asy_syc 时序仿真图由时序仿真图可以看出主时钟Syc_clk 的异步输入信号Asy_in 经该电路后输出同步于主时钟Syc_clk 的Syc_out 信号, 从而实现了异步信号的同步处理按照同步设计原则利用Asy_syc 模块对上述模块二(突发调制器模块)中跨时钟域的信号线Send_data 进行同步处理同步处理模块示意图如图6经实际电路验证得: 同步处理后突发调制器模块运行可靠稳定同样按同样的处理方式对上述模块一(芯片配置模块) 中跨时钟域的信号线进行同步处理经实际电路验证得: 同步处理后,芯片配置模块模块运行可靠稳定图6 同步处理后突发调制器模块框图五总结同步处理模块Asy_syc是一个很好的模块笔者用它和其它的简单模块实现了如下的功能:1. 上沿同步2. 脉冲同步3. 异步系统同步解决了好多Xilinx FPGA设计中棘手的问题参考资料XILINX FUNDATION3.1 TRAINING跨越异步时钟边界传输数据的解决方案 Peter Alfke。
从电路的角度出发,提出了一种新的SOC跨时钟域同步电路设计的方法随着时间的推移,集成电路行业发展至今,已有类似如Intel这样先进的foundry,提出迈入10 nm制程的规划。
高集成度的推行,也使芯片规模越来越大,功能越来越复杂,设计难度越来越高[1]。
SOC的内部时钟的复杂化,导致跨时钟域的接口越来越多。
针对这些异步信号的处理,国外的先驱们提出了很多建设性意见。
但一般用到器件较多,考虑到成本因素,小规模IC将无法承受,并且如果输入脉冲高电平宽度低于最快时钟周期的话,一般无法适用。
因此要想很好地解决这个问题,要处理好4个方面工作:一是如何简化电路;二是如何适应最小输入脉宽的问题;三是解决好亚稳态问题;四是要提高设计可靠性[2]。
1 处理跨时钟域信号的常用方法实际使用时,往往会出现信号在频率不用的时钟域传递的情况,对于这种情况,一般用两种方法处理:结绳法、伴随有效控制信号法。
当信号从一个时钟域进入另一个时钟域的时候,往往出现亚稳态问题[4]。
亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。
当一个触发器进入亚稳态时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平上。
信号同步的目的是防止上一级亚稳态对下一级产生不良影响,采用信号同步的方法就要设计信号同步器。
信号同步器主要有3种:电平同步器、边沿检测同步器、脉冲同步器[7-8]。
但是这些常用方法本身存在缺点和不适应性。
在解决实际问题中,需要根据具体情况,来设计具体的方案。
2 跨时钟域同步电路接口方法组成及工作原理整个电路包括两个时钟域以及一个复位电路。
时钟域1包含一个带有异步复位端的同步触发器。
此触发器带有异步复位端R和同步时钟端CK,低电平产生复位,时钟上升沿开始锁存数据输入端D的状态。
输出端有正相Q、反相/Q两种数据输出。
时钟域2由两个同样的触发器组成,跟前面的一样由异步复位端R和同步时钟端CK,数据输入端D组成。
有一个有趣的现象,众多数字设计特别是与FPGA设计相关的教科书都特别强调整个设计最好采用唯一的时钟域。
换句话说,只有一个独立的网络可以驱动一个设计中所有触发器的时钟端口。
虽然这样可以简化时序分析以及减少很多与多时钟域有关的问题,但是由于FPGA外各种系统限制,只使用一个时钟常常又不现实。
FPGA时常需要在两个不同时钟频率系统之间交换数据,在系统之间通过多I/O接口接收和发送数据,处理异步信号,以及为带门控时钟的低功耗ASIC进行原型验证。
本章讨论一下在FPGA设计中多时钟域和异步信号处理有关的问题和解决方案,并提供实践指导。
这里以及后面章节提到的时钟域,是指一组逻辑,这组逻辑中的所有同步单元(触发器、同步RAM块以及流水乘法器等)都使用同一个网络作为时钟。
假如设计中所有的触发器都使用一个全局网络,比如FPGA的主时钟输入,那么我们说这个设计只有一个时钟域。
假如设计有两个输入时钟,如图1所示,一个时钟给接口1使用,另一给接口2使用,那么我们说这个设计中有两个时钟域。
图1:双时钟域设计平时我们在设计中遇到的门控时钟、衍生时钟以及事件驱动的触发器都可归为时钟域类别。
如图2所示,通过一个简单门控时钟创建了一个新的时钟域。
我们知道,这类时钟控制在FPGA设计中并不被推崇(可以使用时钟使能替代时钟门控),然而它却非常有利于我们理解时钟域这一概念。
本章我们将着重详细讨论以下主题:•两个不同时钟域之间传输信号。
•亚稳态的产生以及对设计的可靠性的影响•通过相位控制避免亚稳态•在时钟域之间传输单个信号,将信号打两拍•使用FIFO在时钟域之间传输多位数据•使用分区同步器模块提高设计的组织架构•处理ASIC验证原型里的门控时钟•建立一个单时钟模块•自动门控移除图2:通过门控时钟创建的时钟域一、跨时钟域设计中包含多时钟域,首先要解决的是在不同时钟域之间传输信号的问题。
信号跨时钟域传输将会是一个大问题,原因如下:1、信号跨时钟域传输产生的故障总是不太容易复现。
快时钟到慢时钟跨时钟域处理随着现代电子技术的不断发展,各种智能设备越来越普及,而这些设备中都包含了各种不同的时钟。
面对不同的时钟,如何进行跨时钟域处理成为了一个重要的问题。
本文将围绕这个问题展开讨论。
一、时钟域时钟域是指在一个系统中,由于时钟信号的不同而形成的不同的时钟区域。
在一个系统中,可能会有多个时钟域,每个时钟域都由一个时钟信号驱动。
例如,一个处理器的时钟域和一个外设的时钟域就是两个不同的时钟域。
二、时钟域的跨越在一个系统中,不同的时钟域之间需要进行数据的传输和交互。
但是,由于不同的时钟域具有不同的时钟频率和时钟相位,因此在传输和交互数据时会遇到一些问题。
例如,如果一个时钟域的时钟频率是100MHz,而另一个时钟域的时钟频率是50MHz,那么在传输数据时就需要进行频率的转换。
又例如,如果一个时钟域的时钟相位发生了变化,那么在传输数据时就需要进行时钟相位的校准。
三、跨时钟域处理的方法为了解决跨时钟域处理的问题,有以下几种方法。
1.同步方法同步方法是指在不同的时钟域之间建立同步信号,使得数据能够在同步信号的边沿进行传输。
这种方法需要在两个时钟域之间建立同步电路,并且需要在同步电路中添加缓存器来保证数据的正确传输。
同步方法的优点是能够保证数据的正确性,缺点是需要额外的硬件开销。
2.异步方法异步方法是指在不同的时钟域之间使用异步传输协议进行数据的传输。
这种方法不需要建立同步电路,只需要使用异步传输协议即可。
异步方法的优点是不需要额外的硬件开销,缺点是在数据传输过程中可能会出现误码。
3.频率转换方法频率转换方法是指将一个时钟域的时钟频率转换成另一个时钟域的时钟频率。
这种方法需要使用时钟控制电路来实现,可以通过倍频或分频的方式实现。
频率转换方法的优点是不需要建立同步电路,缺点是会引入一定的时钟抖动。
4.时钟域转换方法时钟域转换方法是指将一个时钟域的时钟信号转换成另一个时钟域的时钟信号。
这种方法需要使用时钟域转换电路来实现。
跨时钟域的设计参考⾃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!。
1引言可编程系统芯片SOPC的设计过程中经常会遇到如磁盘控制器、CD/DVD-ROM控制器、调制解调器、网络处理器等不同模块或系统间的数据传输。
不同功能模块之间往往使用不同的时钟频率,各模块控制信号和数据总线上的传输速度不同,造成模块接口界面处数据传输速率不匹配,导致控制信息或数据的传输产生错误或者丢失,降低了数据传输的可靠性。
因此,研究采用不同时钟的异步电路SOPC即多时钟域中如何有效实现模块互连、保证数据可靠传输是SOPC设计必须关注的问题。
在SOPC设计中,一般遵循的基本原则是模块内部采用同一时钟,即同步电路的设计策略,各模块间通过接口互连。
只要接口符合异步系统要求的时序规范即可实现多时钟域数据的可靠传输,这是多时钟域SOPC设计的前提。
2多时钟域数据传递中需要解决的主要问题2.1多时钟域数据传输中亚稳态的产生触发器是SOPC设计的基本时序元件,其基本参数是数据的建立时间T set和保持时间T hold。
对于上升沿触发的触发器,T set就是在时钟上升沿到来之前触发器数据端数据保持稳定的最小时间。
而T hold是时钟上升沿到来之后触发器数据端数据继续保持稳定的最小时间。
在T set/T hold之间的小“窗口”内,数据是不确定的,使得触发器工作在一个数据不确定的状态,这种不确定状态就称为亚稳态[1]。
要保证触发器正常工作,在时钟上升沿前后的这个“窗口”内,触发器数据端数据应该保持不变,否则触发器就会进入亚稳态,如图1所示。
单时钟域(同步)电路设计中,由于不存在时钟之间的偏移(Skew)和错位,所以T set和T hold的约束容易满足。
而在有非同步性模块的多时钟域里,若两个时钟之间频率、相位差始终是变化的,即时钟之间的延迟不确定,不同时钟间直接传输数据时T set和T hold的约束难以保证,就会导致亚稳态。
亚稳态产生的数据传输失真还可能导致连锁反应,使整个SOPC系统功能失常。
SOPC设计必须尽量避免亚稳态。
跨时钟域问题处理在FPGA设计中,不太可能只⽤到⼀个时钟。
因此跨时钟域的信号处理问题是我们需要经常⾯对的。
跨时钟域信号如果不处理的话会导致2个问题:(1) 若⾼频率时钟区域输出⼀个脉冲信号给低频率时钟区域,则该脉冲很有可能⽆法被采样到,⽰意图如下,clk2根本采样不到pulse,但是从原理上来说,低频时钟是⽆法完全去采样⾼频信号的,这⾥⾯⼀定会丢失信息。
这是⽆法避免的。
(2) 亚稳态问题在说明亚稳态之前,我们需要先了解什么是建⽴时间和保持时间建⽴时间:在时钟沿到来前,被采样信号应该提前⼀段时间就进⼊稳定状态,这个时间称为建⽴时间保持时间:在时钟沿到来后,被采样的信号应该保持稳定⼀段时间,这个时间称为保持时间⽽亚稳态就是建⽴时间和保持时间不满⾜导致的。
如下图所⽰,就是建⽴时间不满⾜,造成dout是个不确定值,即亚稳态。
很多新⼈以为亚稳态仅仅是逻辑上的障碍,其实亚稳态是实实在在的电路上的问题。
模拟电路中,三极管主要⼯作在其放⼤区间,⽽在数字电路却是要⼯作在截⾄态。
亚稳态⾮常类似模拟电路中的放⼤态,这个状态将使得器件的输出电流被放⼤,如果这个状态被传递,那么将导致更多的电路处在放⼤电路的⼯作状态中,这将引起巨⼤的电流和功耗,甚⾄烧毁芯⽚,所以,跨时钟域是⼀定会出现亚稳态的,但是我们必须要把亚稳态控制在⼀个很⼩的范围内。
这就是为什么要在其后⾯再⽤⼀个寄存器的原因。
它的功能就是把亚稳态仅仅限制在那⼀个寄存器的⼩区域。
亚稳态会造成严重的后果。
就像将军发命令⼀样,若其发出的是⼀个亚稳态的命令,⼠兵A可能判定这个命令为进攻,⼠兵B可能判定这个命令为撤退,这将引起极⼤的混乱。
解决⽅案:1,握⼿操作(⾼频信号要进⼊低频时钟域)针对问题1中所描述的情况,即快时钟域传递⼀个脉冲信号到慢时钟域,慢时钟域很有可能采样不到该脉冲。
这时就需要采⽤握⼿操作来解决了。
⾸先,快时钟域应该将脉冲信号转换为⼀个持续信号,慢时钟域采样到该持续信号后,返回⼀个反馈信号,告知块时钟域将持续信号拉低。
1.1ASYNCHRONOUS INTERFACE – CDCGUIDELINE1.1.1INTRODUCTIONASIC design is becoming more complex due to more and more IP integrated in a chip, and data is frequently transferred from one clock domain to another domain. Clock domain crossing issue becomes more and more important vector in a multi-clock, stable work chip.This document mainly introduce below topics:a. Where will occur CDC;b. What problem will occur due to CDC issue;c. How to design CDC logic correctly.1.1.2APPLICATION AREAIn a multi-clock design, clock domain crossing occurs whenever data is transferred from a flop driven by one clock to a flop driven by another clock. As it is shown in Figure 1-1,Figure 1-1 Clock domain crossing*Note: definition of terminology:Source clock: Clock A in figure 1-1 is defined as source clock;Destination clock: Clock B in figure 1-1 is defined as destination clock;Source clock domain: All the logic design whose reference clock is Clock A, like flip-flop FA in figure 1-1;Destination clock domain: All the logic design whose reference clock is Clock B, like flip-flop FB in figure 1-1;1.1.3PROBLEM DEFINITIONMeta-stability, glitch, multi-fanout and re-convergence may occur in an asynchronous design, they may cause design entering an un-anticipant state and result in function error.1.1.3.1 Meta-stabilitySignal propagate cross asynchronous domains may create meta-stability if setup or hold time violation occurred, shown as figure 1-2.Figure 1-2 Meta-stable issue1.1.3.2 GlitchLogic in the synchronization path result in glitches due to propagation delays, these glitches may get latched and result in false pulses at the synchronizer output, shown as figure 1-3.*Note:synchronization path: below path can be defined as synchronization path,1. Path from source clock domain to destination clock domain, such as the path from Qof DA1/DA2 to the D of DB1 in figure 1-3;2. Path from Q to D of two flip-flops in destination clock domain, such as the path from Qof DB1 to D of DB2 in figure 1-3.Figure 1-3 Glitch issue1.1.3.3 Multi-fanoutMulti-fanout on the synchronization path may result in different value at the synchronizer output due to different propagation delay, shown as figure 1-4.Figure 1-4 Multi-fanout issue1.1.3.4 Re-convergence(信号重汇聚)Re-convergence signals after synchronization may result in functional error, as it is shown as figure 1-5.Figure 1-5 Re-convergence issueRe-convergence logic is a special CDC issue which need logic designer pay more attention to, because all of CDC issue except Re-convergence, like meta-stable, multi-fanout and glitch, could be detected by CDC checking tool(for example cadence’s CONFORMAL). However, some of Re-convergence issue is so complex that it is hard to check by tools, take deep re-convergence issue for example, which is shown as figure 1-6.Figure 1-6, Deep re-convergence issueCLK_A: rhflrhflrhflrhflrhflrhflrhflrhflrCLK_B: llrflrflrflrflrflrflrflrflrflrflrfD0_A: rhhhflllllllllllllllllllllllllllllD0_B: rhhhflllllllllllllllllllllllllllllD0_C: rhhhflllllllllllllllllllllllllllllD0_D: rhhhflllllllllllllllllllllllllllllD1_A: llllrhhhflllllllllllllllllllllllllD1_B: llllrhhhflllllllllllllllllllllllllD1_C: lllllrhhhfllllllllllllllllllllllllD1_D: lllllrhhhfllllllllllllllllllllllllD2_A: llllllllrhhfllllllllllllllllllllllD2_B: llllllllrhhfllllllllllllllllllllllD2_C: lllllllllllrhhflllllllllllllllllllD2_D: lllllllllllrhhflllllllllllllllllllD3_E_syn: lllllllllllrhhflllllllllllllllllllD3_F_syn: llllllllllllllrhhfllllllllllllllllD3_G_syn: llllllllllllll llllll llllllllllllllFigure 1-7 Timing diagram of deep re-convergenceFrom the figure 1-6, it can find that the circuit has two levels re-convergence, the first level re-convergence gate is flip-flop marked with blue color, and the second is flip-flop marked with red color. For cadence CDC tool, it would identify first level re-convergence and report them, but it can not identifysecond level re-convergence. Whichever level re-convergence occurred, it may result in functional error, as it is shown as figure 1-7. It is tool limitation. 1.1.4IMPLEMENTATIONThis chapter introduces several logic schemes to design clock domain crossing logic correctly. These schemes could keep data transferring stably between different clock domains. Nearly all the clock domain crossing issue could be avoided if designer follow the design scheme introduced in the chapter.1.1.4.1 Two synchronizer schemeFor one bit signal cross different clock domain, a general solution is using two flip-flops to sync two cycles in destination clock domain, but its pre-condition is the signal from source clock domain should hold long enough for destination clock to sample, in other words, the frequency of clock A should be less than clock B. Its circuit can be shown as figure 1-8:Figure 1-8 two flip-flop syncWhen use two synchronizer scheme, designer should keep no combinational cell (except inverter and buffer) in CDC path(*note), otherwise, glitch issue shown in figure 1-3 and multi-fanout issue shown in figure 1-4 may occurs. Note:CDC path: the path from Q of flip-flop in source clock domain to the D of flip-flop in destination clock domain, for example, the path from FA/Q to FB1/D in the figure 1-8.As a example of two synchronizer application, figure 1-9/1-10 take glitch and multi-fanout issue for example, shows how to design these logic.Figure 1-9 solution of glitch issueFigure 1-10 solution of multi-fanout issue1.1.4.2 MUX structure sync schemeFor multi-bit signals cross among different clock domain, MUX scheme(shown as figure 1-11) can be used to keep clock domain crossing correctly.MUX scheme adapts to the logic design that, a group of data would transfer form one clock domain to another, and there is a marked signal who indicates data stability when it assert, like Sel in the figure 1-11. Data from source clock keep unchanged until its marked signal detected and two filp-flops synced in destination clock domain, see figure 1-12 for detail.Figure 1-11 MUX structure schemeClock A: lrhflrhflrhflrhflrhflrhflrhflrhflrh Clock B: lrfrfrfrfrfrfrfrfrfrfrfrfrfrfrfrfrData : *ddddddddddddddxddddddddddddddddddxSel : lllrhhhfllllllllllllrhhhfllllllllll Sel_a : lllllrhhhflllllllllllrhhhflllllllll Sel_b : llllllllrhhhflllllllllllrhhflllllllDmux_o:“”””””””xdddddddddddddddxddddddddddDout :“”””””””””*ddddddddddddddd*ddddddddFigure 1-12 MUX scheme timing diagram1.1.4.3 Handshake schemeHandshake is a design based on a protocol that, source clock domain assert request to destination clock domain and will not stop request until it gets the grant from destination clock domain; Destination clock domain receives the request, and continuously asserted grant till it finds the request from source clock domain is de-asserted. Handshake design can be a simple feedback synchronizer, or full handshake or half handshake.1.1.4.3.1 Feedback synchronizerFigure 1-13 shows a logic implementation circuit of feedback synchronizer. For this circuit, there is no limitation between the frequency of clock A and clock B, frequency of clock A could be less than clock B, or more than clock B. However, this circuit adopt to the case that, signal A is consisted of 1T pulse signal and the time from current pulse de-asserted to next pulse asserted is more than (2 clock A + 2 clock B) time.5aa5 a55a 5aa5 a55a 5aa5 a55aFigure 1-13 full feedback synchronizer logicA timing diagram in figure 1-14 shows the work process of full feedback synchronizer circuit.CLKA : lcccccccccccccccccccccccccccccccccc A: lrflllllllrflllllllllllllllllllllll FA0/Q: llrflllllllrfllllllllllllllllllllll FA1/D:llrhhhhhhhfrhhhhhhhflllllllllllllllFA1/Q: lllrhhhhhhhfrhhhhhhhfllllllllllllll FA2/Q: llllllllrhhhhfllrhhhhflllllllllllll FA3/Q: lllllllllrhhhhfllrhhhhfllllllllllll CLKB :lrfrfrfrfrfrfrfrfrfrfrfrfrfrfrfrfrf FB1/Q:lllllrhhhhhflrhhhhhflllllllllllllll FB2/Q:lllllllrhhhhhflrhhhhhflllllllllllll FB3/Q:lllllllllrhhhhhflrhhhhhflllllllllll B:lllllllllrhhhhhflrhhhhhflllllllllllFigure 1-14 full feedback synchronizer timingFigure 1-15 shows a simple feedback synchronizer logic which may usuallyuse in logic design, and figure 1-16 is its timing diagram.Figure 1-15 Simple feedback synchronizer logicFigure 1-16 Simple timing diagram of feedback synchronizer1.1.4.3.2 REQ-GNT schemeFigure 1-17 shows the handshake implementation principle. Request and grant transfer between Tx and Rx need to double synchronization, and data need to hold until Tx receive grant disable.Figure 1-17 handshake implementationFull handshake flow(see figure 1-18):1. Tx asserts request signal (REQ) to Rx;2. When Rx receives request (RE Q _B1), it asserts grant signal (GNT) to Tx;3. When Tx detect grant signal (GNT_A1), it dis-asserts its request;4. Finally, Rx detect request dis-assert, it also dis-assert its grant;5. When Tx detect grant dis-assert, this transfer finish.Figure 1-18 Full handshake timing diagramFull handshake will occupy five clock cycles in Tx domain and six clock cycles in Rx clock domain. Full handshake is a safest mode to implement data transfer for Tx and Rx always know status each other.Half-handshake is same as full handshake except Tx/Rx dis-assert their request/grant signals before receiving response.1.1.4.4 Asynchronous FIFO synchronizer schemeWhen data burst transfer between two clock domain, FIFO synchronizer is a common solution.Figure 1-19 show the implementation diagram of FIFO synchronizer, it include dual-port RAM, write/read control module and two flop-flops synchronizer.In the implementation of FIFO synchronizer, the key issue is FIFO status indicator signal generation, they are full, half full, empty, half empty. Generally, write/read pointer use gray code, then they can use two flip-flops synchronizer to sync directly.wclk wfullwinc wdatarclkremptyrincrdata Figure 1-19 Dual-clock asynchronous FIFO2n-Queue FIFO is a typical example of asynchronous FIFO, who is a small FIFO whose depth is 2n, any value can be assigned to n according to design need. Theoretically, 2n-Queue FIFO can stably transfer signal in a logic whose frequency of source clock is n times as fast as destination clock.Detail verilog code implementation of 2n-Queue FIFO can be seen Appendix A (2n-Queue FIFO implementation code).1.1.5LAYOUT GUIDENo1.1.6LIMITATIONNo1.1.7APPENDIX A2n-Queue FIFO implementation code:module USBD_ASFF2(RST_, ICLK, OCLK, DIN, FULL, OUTE, OUTD) ; input RST_ ;input ICLK ; //Write domain clockinput OCLK ; //Read domain clockinput DIN ; //write active indicatoroutput FULL;output OUTE,OUTD;parameter PTR_1BIT=1;reg[PTR_1BIT:0] WR_PTR,RD_PTR ; ///read/write address, gray code reg FULL ;wire [PTR_1BIT:0] Wr_Ptr_Nxt ;wire [PTR_1BIT:0] Rd_Ptr_Nxt ;wire [PTR_1BIT:0] Rd_Ptr_Wclk ; //readwire [PTR_1BIT:0] Wr_Ptr_Rclk ;reg EMPTY;/************************* define gray count************************/parameter gray0 = 2'b00,gray1 = 2'b01,gray2 = 2'b11,gray3 = 2'b10;/************************************************ translation of signals ==> RD connects to the EMPTY for***********************************************/wire RD = !EMPTY;/************************************************ Write point* - when DIN is active, go to next gray count***********************************************/// always@(WR_PTR or DIN) Wr_Ptr_Nxt <= #1 gray_inc(WR_PTR) ; // chad;assign Wr_Ptr_Nxt = gray_inc(WR_PTR);always@(posedge ICLK or negedge RST_ ) beginif( !RST_ ) beginWR_PTR <= 2'b0 ;end else if( DIN) beginWR_PTR <= Wr_Ptr_Nxt ;endend/************************************************ Read point* - when RD is active, go to next gray count***********************************************/// always@(RD_PTR or RD ) Rd_Ptr_Nxt <= #1 gray_inc(RD_PTR) ;// chad;assign Rd_Ptr_Nxt = gray_inc(RD_PTR);always@(posedge OCLK or negedge RST_ ) beginif( !RST_ ) beginRD_PTR <= 2'b0 ;end else if( RD ) beginRD_PTR <= Rd_Ptr_Nxt ;endend/******************************************* Full condition* - sync read pointer to write clock domain******************************************/USBD_CDCS DNT_FL1(.Q(Rd_Ptr_Wclk[1]),.D(RD_PTR[1]),.CK(ICLK),.R(RST_)); USBD_CDCS DNT_FL0(.Q(Rd_Ptr_Wclk[0]),.D(RD_PTR[0]),.CK(ICLK),.R(RST_));wire NFull= DIN &(Wr_Ptr_Nxt[0]==(~Rd_Ptr_Wclk[0]) & Wr_Ptr_Nxt[1]==(~Rd_Ptr_Wclk[1])); wire FullX = NFull |(WR_PTR[0]==(~Rd_Ptr_Wclk[0]) & WR_PTR[1]==(~Rd_Ptr_Wclk[1]));always@(posedge ICLK or negedge RST_ )if( !RST_ ) FULL <= 1'b0 ;else FULL <= FullX ;/************************************************ EMPTY* - sync write pointer to read clock domian***********************************************/USBD_CDCS DNT_EP1(.Q(Wr_Ptr_Rclk[1]),.D(WR_PTR[1]),.CK(OCLK),.R(RST_)); USBD_CDCS DNT_EP0(.Q(Wr_Ptr_Rclk[0]),.D(WR_PTR[0]),.CK(OCLK),.R(RST_));wire NEMPTY = (Rd_Ptr_Nxt == Wr_Ptr_Rclk) & RD ; wire EMPTYX = (RD_PTR == Wr_Ptr_Rclk) ;wire EMPTYD = NEMPTY | EMPTYX ;always@( posedge OCLK or negedge RST_ ) begin if( !RST_ ) EMPTY <= 1'b1 ;else EMPTY <= EMPTYD ;endwire OUTD = !EMPTYD;wire OUTE = !EMPTY;function[PTR_1BIT:0] gray_inc ;input[PTR_1BIT:0] gray ;begincase(gray) // synopsys parallel_case full_casegray0 : gray_inc = gray1 ;gray1 : gray_inc = gray2 ;gray2 : gray_inc = gray3 ;gray3 : gray_inc = gray0 ;default:gray_inc = 2'bxx;endcaseendendfunctionendmodulemodule USBD_CDCS(R, CK, D, Q);input R;input CK;input D;output Q;reg Q;reg QX;always @ (negedge R or negedge CK)beginif (~R)QX <= 1'b0;elseQX <= D;endalways @ (negedge R or posedge CK) beginif (~R)Q <= 1'b0;elseQ <= QX;endendmodule。