跨时钟域设计问题与方法
FPGA设计中跨时钟域的问题与方法

图2 :反馈方式设计电路
f
— — —— — —— —驯
f
T l x l 一 一
M L _ _
+ l — — — 衄 l
+ .
n^ ^ ¨
【 关键词 】F P G A跨 时钟域 亚稳 态
3 . 2多结构 同步设计
对 于多位信 号在不 同的时钟域之 问传输 , 多路复用设计可 以保持跨 时钟 域传 输时的正确 Ar r a y), 即 现 场 可 编 程 门 阵 列 , 它 是 在 性 ,如下 图所示 。多路 复用 设计可以适用于如 P A L、GAL、C P L D 等可编 程期 间的基 础上进 下的设计 中,一组数据 需要 从一个 时钟域传输 步发展起 来的一种可编程 门阵列 。它是作 为 到另外一个时钟域 ;当断言时,有标 记的表明 专用 集成 电路 ( A S I c)领 用 中的一 种 半定制 数据信号稳定的一组信号 。 电路而 出现 的,既解决 了定制 电路 的不足 ,又 . 3握 手设 计 克服 了原 有可 编程 期 间 门 电路 数 目有 限的缺 3
误。
亚 稳态 现象 :数 字信 号通 过异 步 时钟域 时,如果时钟信号 不能满 足触发器的建立时 间 或保持时间 ,此时很可 能产生亚 稳态现象。 毛刺 现 象: 同步逻 辑 电路 中产 生毛 刺现 象主要取决 于数字 信号传播时延 ,这些毛刺有
可能会被成功锁存 ,也有可能导致错误脉冲在 同步装置 中输 出。 多扇 出现象 :在 同步 逻辑 电路 中,由于
握 手 设计 是基 于 以下协 议进 行 设计 的: 源 时钟域 向目的时钟域发 出请求 ,而且该请 求 信 号一直保持着,直到源时钟域接受到 目的时 钟 域的返回信号 ;目的时钟域接收到请求信 号 之 后,连 续不断地发送确认信号 ,直到其接 收 到源 时钟域是重复断言 的。握手机制可 以设计 为 简单 的反馈 同步器,也可 以设计为全握手机 制或者 半握手机 制。 3 . 3 . 1 反馈 同步 设计 对于图 2 所示 ,使 用 的是反 馈 同步 设计 实 现 的逻辑 电路。对 于 该 电路来 讲 ,时钟 A 和 时钟 B之间的频率差值是没有极 限要求 的, 时 钟 A 的频率 可 以比时钟 B的频 率低 ,也可 以 比时 钟 B 的频率 高。然 而该 电路 使用 的是 信 号 A 由一个 时钟 周期 组成 ,而且从 当 前脉 冲到下一个脉冲 的时 间间隔要 大于两倍的时钟 A和 两倍的时钟 B的时 间之和 。 3 - 3 . 2请求 . 应答 设计 请求和 回答 传输方式在 发送信 号 T x和 接 收信号 R x之间需要双 重 同步 ,而且数据 的保 持时间必 须保持 到发送信 号 T x收到确认无 效 之后,如图 3所示。
Xilinx FPGA 设计中的跨时钟域问题

浅谈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跨时钟域同步电路设计的方法

从电路的角度出发,提出了一种新的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外各种系统限制,只使用一个时钟常常又不现实。
FPGA时常需要在两个不同时钟频率系统之间交换数据,在系统之间通过多I/O接口接收和发送数据,处理异步信号,以及为带门控时钟的低功耗ASIC进行原型验证。
本章讨论一下在FPGA设计中多时钟域和异步信号处理有关的问题和解决方案,并提供实践指导。
这里以及后面章节提到的时钟域,是指一组逻辑,这组逻辑中的所有同步单元(触发器、同步RAM块以及流水乘法器等)都使用同一个网络作为时钟。
假如设计中所有的触发器都使用一个全局网络,比如FPGA的主时钟输入,那么我们说这个设计只有一个时钟域。
假如设计有两个输入时钟,如图1所示,一个时钟给接口1使用,另一给接口2使用,那么我们说这个设计中有两个时钟域。
图1:双时钟域设计平时我们在设计中遇到的门控时钟、衍生时钟以及事件驱动的触发器都可归为时钟域类别。
如图2所示,通过一个简单门控时钟创建了一个新的时钟域。
我们知道,这类时钟控制在FPGA设计中并不被推崇(可以使用时钟使能替代时钟门控),然而它却非常有利于我们理解时钟域这一概念。
本章我们将着重详细讨论以下主题:•两个不同时钟域之间传输信号。
•亚稳态的产生以及对设计的可靠性的影响•通过相位控制避免亚稳态•在时钟域之间传输单个信号,将信号打两拍•使用FIFO在时钟域之间传输多位数据•使用分区同步器模块提高设计的组织架构•处理ASIC验证原型里的门控时钟•建立一个单时钟模块•自动门控移除图2:通过门控时钟创建的时钟域一、跨时钟域设计中包含多时钟域,首先要解决的是在不同时钟域之间传输信号的问题。
信号跨时钟域传输将会是一个大问题,原因如下:1、信号跨时钟域传输产生的故障总是不太容易复现。
ASIC系统中跨时钟域配置模块的设计与实现

!"# !"#$%&’#$()*+,
配置模块和功能模块的接口可以采用两种设 计方式 "如图 "! 一种方式是直接通过连线将配置寄 存器的值输入功能模块 " 一旦配置寄存器的值改变 了 " 马上会影响 相 应 功 能 模 块 的 操 作 # 另 一 种 方 式 是配 置 寄 存 器 的 值 通 过 一 个 数 据 有 效 信 号 以 数 据 加地址的方式输入功能模块 " 在功能模块经过二级 地址译码将配置寄存器的值锁存在本地寄存器 $ 功 能模块内部 % 中 & 第一种接口方式实现简单 " 但是接 口之间的连线就会很多 " 例如有 #( 个宽度为 )"*+,的配置寄存器的值需要输入功能模块 #" 那么配置 模块和功能模块 # 之间的连线就有 )"( 条 # 而如果 采用第二种接口方式 "只需要有 )"*+,- 数据线 ’!*+,地址线以及 #*+, 数据有效信号 " 两模块之间的连线 为 ). 条 !
A2;<19"
对于响应型通讯协议 ! 当 ()* 进行读配置寄存 操作时 !()* 发起请求后 ! 只有当被请求的 %&’( 系 统返回一个读有效信号 %AFGHD! 低为有效 & 时 !
()* 数据总线上才是有效的读取数据 $ 同样当 ()* 进行写配置寄 存 器 的 操 作 时 !()* 发 起 请 求 后 ! 只 有 当 被 请 求 的 %&’( 系 统 返 回 一 个 写 有 效 信 号 7AFGHD ! 低为有效6时 !()* 写操作才能结束 " 对于非响应型通讯协议 ! 当 ()* 进行读配置寄 存器操作时 !()* 发起请求 ! 经过固定的 ()* 时钟
(完整版)fpga跨时钟域设计

DPRAM的实际地址 4bit GRAY读\写 ptr 3bit GRAY读\写addr
0
0_000
000
奇
1
0_001
001
数
2
0_011
011
次
3
0_010
010
读
4
0_110
110
\
5
0_111
111
写
6
0_101
101
7
0_100
100
0
1_100
000
偶
1
1_101
001
数
2
1_111
▪ 读写指针比较产生
▪ 同步FIFO直接把读写时钟比较或运算产生 ▪ 异步FIFO由于读写指针不同时钟域,比较前
指针必须同步化 ▪ 由于二进制的指针会出现多位同时跳变,直
接由同步器进行同步化会有问题
异步FIFO设计
根据full和empty产生方法分为: 1. Binary Code 结合保持握手
011
次
3
1_110
010
读
4
1_010
110
\
5
1_011
111
写
6
1_001
101
7
1_000
100
DPRAM的实际地址 4bit GRAY读\写 ptr 低3bit 二进制读\写addr
0
0_000
0_000
奇
1
0_001
0_001
数
2
0_011
0_010
次
3
0_010
0_011
读
4
快时钟到慢时钟跨时钟域处理

快时钟到慢时钟跨时钟域处理随着现代电子技术的不断发展,各种智能设备越来越普及,而这些设备中都包含了各种不同的时钟。
面对不同的时钟,如何进行跨时钟域处理成为了一个重要的问题。
本文将围绕这个问题展开讨论。
一、时钟域时钟域是指在一个系统中,由于时钟信号的不同而形成的不同的时钟区域。
在一个系统中,可能会有多个时钟域,每个时钟域都由一个时钟信号驱动。
例如,一个处理器的时钟域和一个外设的时钟域就是两个不同的时钟域。
二、时钟域的跨越在一个系统中,不同的时钟域之间需要进行数据的传输和交互。
但是,由于不同的时钟域具有不同的时钟频率和时钟相位,因此在传输和交互数据时会遇到一些问题。
例如,如果一个时钟域的时钟频率是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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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。