一、脉冲同步
signal_a是clka(300M)时钟域的一个单时钟脉冲信号,如何将其同步到时钟域clkb(100M)中,并产生出signal_b同步脉冲信号。请用Verilog代码描述,并画出对应的时序波形图说明图。
1.1 电路波形图
如上图所述,aclk快时钟域发送的信号signal_a,慢时钟域的时钟bclk根本就采集不到,此时不能使用打两拍的方式,要想办法转换思路,如果能够让同步于快时钟域aclk下的脉冲信号signal_a变长到可以让慢时钟域bclk检测到,那么这个问题就可以完美解决了。
所以先将快时钟域clka下的脉冲信号signal_a,在快时钟域clka的作用下,变为沿信号,产生一个名为adata的中间变量来作为脉冲信号signal_a的沿信号。如上图所示,每当快时钟域aclk检测到signal_a脉冲信号为高时,让adata信号取反,使得signal_a的第一个脉冲变为adata信号的上升沿,signal_a的第二个脉冲变为adata信号的下降沿,后面如果Signal_a信号还有脉冲依然是变为adata信号的上升沿和下降沿。
巧妙的利用将“脉冲信号”转化为“沿信号”的思想就可以使慢时钟域的时钟bclk检测到同步于快时钟域aclk且将脉冲信号signal_a转化为沿信号adata,相当于是把同步于快时钟域aclk的脉冲信号signal_a进行了展宽处理,这样我们就把快时钟域aclk的脉冲信号signal_a通过adata信号“沿”的形式在慢时钟域bclk中得到了保留。
接着,我们再对adata信号做打两拍的处理就可以将adata信号同步到慢时钟域clkb中了。bdata0信号是adata信号在慢时钟域bclk下打的第一拍,bdata1信号是adata信号在慢速时钟域bclk下打第二拍,bdata1就是同步于慢速时钟域bclk的稳定信号。
最后,采用边沿检测的方法,将变为bdata1信号的“沿”再转化为脉冲信号,这里我们使用的方法是采用异或门。需要注意的是不能直接使用bdata0和bdata1来产生沿标志信号,因为bdata0信号的不稳定性可能会导致产生的沿信号也不稳定,所以需要将bdata1信号再打一拍,产生signal_b信号。
1.2 代码
module pulse_synchronization(
input aclk,
input arst_n,
input signal_a,
input bclk,
input brst_n,
output signal_b
);
reg adata;
reg bdata0;
reg bdata1;
reg bdata2;
always@(posedge aclk or negedge arst_n)
begin
if(arst_n==1'b0)
adata<=1'b0;
else
adata<=adata^signal_a;
end
always@(posedge bclk or negedge brst_n)
begin
if(brst_n==1'b0)
begin
bdata0<=1'b0;
bdata1<=1'b0;
bdata2<=1'b0;
end
else
begin
bdata0<=adata;
bdata1<=bdata0;
bdata2<=bdata1;
end
end
assign signal_b=bdata1^bdata2;
endmodule
所以,脉冲同步一般适用于单比特信号从快时钟域传递慢时钟域的场景。
1.3 局限
如上情况,signal_a是两个脉冲,但是使用“脉冲同步”同步到bclk时钟域确只有一个脉冲了,在使用“脉冲同步”时应注意这一点。