【面试】【数字IC基础】跨时钟域处理一(CDC,Clock Domain Crossing)(一)

发布时间:2026/8/12 18:35:38
【面试】【数字IC基础】跨时钟域处理一(CDC,Clock Domain Crossing)(一) 【缘起】最近投实习有问到CDC但是那会儿只会双DFF所以后来稍微整理了一下超入门篇想着用最通俗易懂的语言记录一下以及难get的点详细说明了一下一、概述跨时钟域处理主要分为单比特和多比特的处理方法这一篇先讲单比特的处理方法。二、单bit信号跨时钟域处理方法2.1电平信号无论是快时钟域→慢时钟域还是慢时钟域→快时钟都直接用双DFF就好如下图的电路图电平信号无论是高电平还是低电平都会持续较久的时间脉冲信号是只持续一个周期类似这样看上面电路图比如我们用clk2去采用clk1下的这个电平信号就是有可能会采到上升/下降沿对吧那么就会产生亚稳态我们又知道亚稳态会在后面的组合逻辑里一直往下传递甚至放大这样输出的结果就不对。所以我们采用打拍的方式当加了第一个触发器后由于亚稳态发生的概率公式可知已经减小很多了通过第二个触发器亚稳态传播到后续逻辑的概率会大幅降低通常降到 10−15 量级即可接受范围是在我们可以接受的范围内。感兴趣的可以去看一下详细的公式推导具体代码及解析如下关于上述电路图如果 a 本身是 clk1 域产生的信号这一步AA可以省略如果 a 是外部异步输入则需要先用 clk1 采样一次消除毛刺。2.2脉冲信号1.慢到快先双DFF再边沿检测再看由快时钟去采慢时钟的信号vld1是慢时钟产生的一个脉冲信号较宽可以看到在clk2下会产生vld2但是clk2较快所以产生的vld2就不是一个脉冲信号了途中持续了两个周期2.快到慢先脉冲信号展宽转换为电平信号再双DFF最后边沿检测得到脉冲信号用一个慢速时钟去采快速时钟的时候如图可能每次都错过上升沿每次都采到的是0就相当于采不到因此我们要先拓宽脉冲。上图展示了由慢速去采样快速时钟域具体是如何做CDC的。①信号a是由clk1产生的我们的目的是让clk2不把a当作毛刺给过滤掉在图中我们可以看得到clk2无论哪个上升沿都采不到信号a而且a只是一个脉冲信号非常非常短很有可能直接当毛刺过掉了所以我们需要构造一个a_latch把它变成电平信号信号展宽当clk2采样后再拉低②现在a_latch是一个电平信号就回到我们上面电平信号的CDC处理方式得到b_latcch_r但是我们还需要构造一个b_lach_2r,检测上升信号的脉冲沿也会同时将其转换为脉冲信号得到clk2上的b信号③构造反馈信号当clk2上采到信号后即b拉高就会产生反馈信号告诉外界已经采样完毕这样会形成一个闭环的CDC④把反馈信号跨到clk1上方法同理还是双DFF⑤最后产生一个busy信号拒绝新的握手请求【上述握手协议主要针对快 → 慢场景脉冲最危险的方向。如果明确是慢 → 快可以简化为双 DFF 边沿检测不需要展宽和反馈。但握手协议在时钟频率比不确定时也能安全工作鲁棒性更强。】2.3数据信号总的原则就是等数据稳定后再CDC那什么时候稳定呢我们可以让valid先跨时钟等valid过去后说明数据已经维持某一个值较长时间了就不会采到亚稳态时的值。因此先对valid跨时钟再用跨完时钟后的valid去采样数据。如下图代码就是先对valid2用脉冲的CDC处理方式最后加上data的处理就好三、总结3.1知识点总结这节主要讲单bit信号和数据传输表格汇总如下数据CDC则在此基础上用跨完后的valid控制信号去采样即可信号类型快 → 慢同步到慢时钟域慢 → 快同步到快时钟域电平信号如busy、enable直接双 DFF直接双 DFF脉冲信号如start、done展宽成电平 → 双 DFF → 边沿检测还原脉冲双 DFF → 边沿检测还原脉冲3.2记住小技巧1.知识体系如果看这个博客是正准备秋招或者面试ddl可以主要看下面这个目录记得CDC不同类型解决方法⭐⭐⭐、跨时钟域主要的问题⭐⭐2.本节记忆如果前期积累不太深厚ddl的压力的话可能记不住尤其是快到慢和慢到快具体是谁需要展宽可以这样形象记忆/*慢时钟就是一个内敛慢热的快时钟就是热情开朗的快采样慢慢跨到快因为热情开朗嘛所以散发的信号很明显就不用搞那么复杂直接双DFF边沿采样就好。这个就是快时钟去采样慢时钟也就是慢时钟跨到快时钟这里来你想嘛人家慢时钟都跨越千山万水来了所以肯定是主人快时钟要主动采样呀慢采样快快时钟域到慢时钟那慢热的散发的信号就很含蓄人热情开朗大大咧咧很可能就get不到呀那么怎么办呢就需要慢热的持续久一点总有一天能get到咯~(也就是咱们说的要先展宽脉冲嘛)。具体来说因为慢时钟的采样频率低它可能连续多个周期都“错过”了快时钟域里那个短暂的高电平脉冲。为了让慢时钟能稳定地捕捉到这个信号我们必须先在快时钟域内将这个脉冲“展宽”——也就是通过一个锁存器latch或触发器把脉冲信号变成一个持续多个快时钟周期的电平信号。这样即使慢时钟的采样点比较稀疏也有足够高的概率在电平信号为高时采样到它。展宽后的电平信号再经过双 DFF 同步到慢时钟域最后通过边沿检测电路还原成一个干净的脉冲信号。这个 过程就像两个性格不同的人沟通急性子快时钟说话快、动作快但慢性子慢时钟反应慢所以急性子需要把重要的话多说几遍、持续久一点慢性子才能听清楚并做出回应。嘿嘿~这么浪漫的比喻当然要用一个漂亮的颜色咯~*/如果时间充裕的话还是建议手写代码理解会深刻很多3.3小小面经我面的两个关于这一节都是会在单bit的详细问了后向多bit的过渡单bit的快→慢和慢→快都会问然后再过渡和引导到异步FIFO如何设计一般这一节面试官都是会让画时序图所以时间充裕可以画画以及提前演练讲解。四、参考资料1.原创讲解视频全网最好玩儿的跨时钟域CDC教程_哔哩哔哩_bilibili2.参考资料【数字IC基础】跨时钟域CDCClock Domain Crossing-CSDN博客《数字IC设计入门》2.23 跨时钟域异步处理方法_哔哩哔哩_bilibili附录 问题汇总【这一part主要是汇总在学习过程中可能产生的问题基础较好的或者没啥疑问的可自行略过】1.边沿检测原理因为边沿检测原理还是很可能会被面试官问到而且可能初学者一开始没那么懂所以放到这儿波形图不明白的话可以看真值表比较好理解b_2r (上一拍)b_r (现在)b b_r ~b_2r含义000一直是低没变化011上一拍低现在高 → 上升沿100上一拍高现在低 → 下降沿110一直是高没变化只有第二行输出 1。这就是检测到上升沿的数学表达。1.关于 b_latch_2r 的作用b_latch_2r的唯一目的是边沿检测检测b_latch_r的上升沿。而产生单周期脉冲只是边沿检测的自然结果不是额外目的。如果没有 b_latch_2r 做边沿检测b_latch_r是一个持续多拍的电平因为a_latch被展宽了如果直接把b_latch_r当输出用clk2 域收到的就是一个长电平不是脉冲边沿检测把它还原成了只高 1 拍的脉冲2.为什么脉冲要先展宽成电平再跨时钟域假设不展宽直接跨clk1 200MHz周期 5nsclk2 50MHz周期 20nsa脉冲只持续5ns1 个 clk1 周期clk2 每 20ns 才采样一次。三种可能情况结果概率a脉冲刚好落在 clk2 上升沿附近clk2 采样到但可能亚稳态很低a脉冲落在 clk2 上升沿之间clk2 完全看不到这个脉冲很高a脉冲跨越 clk2 两个沿被采样到中等核心问题快时钟的窄脉冲慢时钟大概率漏掉。展宽成电平后a_latch被a置 1 后持续保持高电平不管 clk2 什么时候来采样它一定能看到a_latch1采到后通过反馈机制清零准备下一次。这就是脉冲 → 电平 → 跨时钟域 → 边沿检测还原脉冲的完整逻辑。如果是慢时钟域 → 快时钟域50MHz → 200MHz慢时钟的脉冲宽度 20ns快时钟周期 5ns快时钟一定能采到不会漏。但快时钟会采到连续 4 次 1所以也需要边沿检测还原成单脉冲。3.为什么两个触发器就能解决亚稳态三个或四个不行吗这是概率问题不是能不能的问题。亚稳态的物理本质触发器进入亚稳态后输出不会永远震荡。它会指数衰减最终稳定到 0 或 1具体是哪个不可预测但一定会稳定。根据概率公式可知通过两级后已经能降低到我们能接受的范围。4.为何要构造b_feedback_latch?如果没有则是开环的CDCclk1: a_latch1 ──CDC──► clk2: 采样到了吗不知道...↓clk1: a_latch 什么时候清零不知道...我们需要构造闭环的CDCclk1 发请求 ──► clk2 收到 ──► clk2 发 ACK ──► clk1 收到 ACK ──► clk1 清零↑___________________________________________________________↓那就到这咯祝大家学有所成、面试全过。