单比特的跨时钟域问题
简介
跨时钟域(CDC)主要分为单比特和数据流两种,数据流的跨时钟域一般用到异步FIFO来进行数据的缓冲,利用FIFO的读写满空这些状态来判断。而单比特的跨时钟域可以不用到FIFO来处理。
单比特主要分为两种,一种是由慢时钟域到快时钟域,这种情况比较容易解决,因为快时钟域是肯定可以“看见”慢时钟域的,解决方法也就比较灵活了,这里介绍“取反法”和“打拍法”(名字随便叫的--);
还有一种情况是由快时钟域到慢时钟域,此时慢时钟域已经“看不见”快时钟域了,情况也就变得比较复杂了,这里也介绍两种方法:“取反法”和“握手信号反馈法”。(名字依旧那么随便--)。
单比特慢时钟域到快时钟域
“取反法”
这个模块有三个输入(蓝色标记)、一个输出(红色标记);In_b在慢时钟B下已经是同步脉冲了,此时中间信号state_b在慢时钟域B下对In_b取反。再去识别state_b的沿变化即可。在快时钟域下对state_b打两拍(消除亚稳态),第二拍的信号是可以在快时钟域下使用的,再对state_b2打一拍用于识别state_b2的沿变化。这种方法叫脉冲同步法,但是我觉得“取反法”的名字更加容易记住。代码如下:
module CDC_fast2slow( input wire fastClk,
input wire slowClk,
input wire rst,
input wire slowIn,//需要同步的慢时钟脉冲
output wire fastOut //同步好的快时钟脉冲
);
reg state_slow; //在慢时钟域下对脉冲取反
reg state_slow1; //在快时钟域下打拍
reg state_slow2;
reg state_slow3;
//在慢时钟域下对脉冲取反 ;state_slow
always@(posedge slowClk or negedge rst)
if(!rst)
state_slow<=1'b0;
else if(slowIn)
state_slow<=~state_slow;
// 在快时钟域下打拍
always@(posedge fastClk or negedge rst)
if(!rst