前言
嗨,嗨,来继续学习CDC相关问题~
微信关注《FPGA学习者》获取更多精彩内容
【书接上文】笔试|面试|FPGA知识点大全系列(11)跨时钟域问题大全解(上)
③闭环传输(握手/反馈机制)
上一期中脉冲同步器,其实就是一种开环方案,将目标信号进行展宽到至少超过接收时钟域的时钟周期,上期也提到,最佳脉宽至少为采样周期的1.5倍(即两个脉冲间的间隔),开环解决方案,多用于相关时钟频率固定且时钟信号能够被正确分析。
这种方案好处是能在无须接收时钟域的握手信号的情况下最快地将信号传递通过跨时钟域边界。 但这并不是一种通用的解决方案,下面介绍另一种方案,闭环处理。
如图所示:
该闭环方案的思路是这样的,在快时钟域输入单bit的控制信号(信号拉高),通过快时钟域缓存一拍后在慢时钟域通过两级触发器做同步,将同步后的信号返回给快时钟域进行同步、采样,重点来了,我们要使用这个反馈回来的信号来控制单bit的控制信号是否拉低;
如此一来,相当于利用反馈信号来延长快时钟域的输入信号,从而使慢时钟域能够准确地采集到该控制信号。
所以上图仅仅是一个思路框图,并不是最终的解决办法电路图;
这种方案的好处是: 反馈回来的同步信号可以非常安全地确认第一个是使能控制信号已经被接收时钟域正确识别和采样;
缺点是: 这种信号传递方式存在相当大的延时,因为信号未被接收时钟域正确的接收之前是不能被释放的,也就无法传递信号的下一个控制信号。
下面展示的是一种闭环控制的方案框图和代码:
`timescale 1ns/1ns
//design by FPGA学习
module test(
input clk1,
input clk2,
input rst_n1,
input rst_n2,
input data_in,
output reg b2,
output reg Qa2
);
reg a;
always@(posedge clk1 or negedge rst_n1)begin
if(~rst_n1)begin
a <= 1'b0;
end
else if(a && ~Qa2) //说明输入的为1,但是反馈回来的为0,没采集成功
a <= 1'b1; //没采集成功就要延长高电平时间继续采集
else
a <= data_in;
end
reg b1;
always@(posedge clk2 or negedge rst_n2)begin
if(~rst_n2)begin
b1 <= 0;
b2 <= 0;
end
else begin
b1 <= a;
b2 <= b1;
end
end
reg Qa1;
always@(posedge clk1 or negedge rst_n1)begin
if(~rst_n1)begin
Qa1 <= 0;
Qa2 <= 0;
end
else begin
Qa1 <= b2;
Qa2 <= Qa1;
end
end
endmodule
下图是仿真图,
上图中,a为快时钟域第一级触发器信号,b2为最终输出,Qa2为反馈回的信号,在黄线地方,检测到Qa2为高电平,说明正确接收,a在下一个时刻就会被拉低,不再进行信号的延长。
这种方法的缺点在仿真图中也看得出来,正确接收一个控制信号用的时间比较长,得等Qa2变为低电平后才能进行下一次的单bit控制信号输入。
如图所示,红色框内,控制信号来得太“早”了,上一个信号的反馈信号还没有结束,这时,该控制信号就被丢失了。
4.多bit信号的跨时钟域传输
前面提到过,多bit信号一般为数据信号;多bit信号跨时钟域传输也就是数据总线信号的的传输;那么,类比于单bit数据跨时钟域传输,一个很自然的想法出现了:
有没一种可能,直接通过一组触发器对数据总线信号利用打两拍的方式进行同步呢?
为什么呢?
在FPGA内部,每个寄存器的位置都不同,不同的布局布线逻辑,会导致总线中的每一个数据到达寄存器时产生的延迟不同,这个延迟又会随着打拍数的增加、数据位宽的增加、时钟频率的增大而变得更加恶劣,所以数据在传输过程中很可能:传着传着就传错了。
如下图所示:
再加上这个图,看得就比较清楚了。
来具体看看怎么解决多bit信号跨时钟域传输的问题。
①DMUX同步器
英文应该是Demultiplexer,数据分配器;该方法适合带数据有效标志信号的多bit数据做跨时钟域传输,其原理框图如下:
🐘对单bit的数据有效标志信号在B时钟域打两拍;
🐘数据有效信号为高电平时,说明此时数据也处于稳定状态,在这种情况下慢时钟域寄存器对信号进行采样,可以保证没有setup/hold违例。其实同步后的数据有效标志信号充当的是使能信号。
代码如下:
`timescale 1ns/1ns
module mux(
input clk_a ,
input clk_b ,
input arstn ,
input brstn ,
input [3:0] data_in ,
input data_en ,
output reg [3:0] dataout
);
reg [3:0] data_in_r;
always@(posedge clk_a or negedge arstn)begin
if(~arstn)
data_in_r <= 4'd0;
else
data_in_r <= data_in;
end
reg data_en_ra;
always@(posedge clk_a or negedge arstn)begin
if(~arstn)
data_en_ra <= 1'b0;
else
data_en_ra <= data_en;
end
reg data_en_ra_r1,data_en_ra_r2;
always@(posedge clk_b or negedge brstn)begin
if(~brstn)begin
data_en_ra_r1 <= 1'b0;
data_en_ra_r2 <= 1'b0;
end
else begin
data_en_ra_r1 <= data_en_ra;
data_en_ra_r2 <= data_en_ra_r1;
end
end
always@(posedge clk_b or negedge brstn)begin
if(~brstn)
dataout <= 4'd0;
else begin
case(data_en_ra_r2)
1'b0:dataout <= dataout;
1'b1:dataout <= data_in_r;
endcase
end
end
endmodule
其实,该代码就是牛客网Verilog刷题进阶挑战的第24题
②异步FIFO传输
异步FIFO适合在有大量的数据需要进行跨时钟域传输,并且对数据传输速度要求比较高的场合
异步FIFO的设计在之前已经进行了详细的说明,详见笔试|面试|FPGA知识点大全系列(7)之异步FIFO设计,无论是在跨时钟域还是同时钟域,亦或是快时钟域到慢时钟域、慢时钟域到快时钟域;异步FIFO都能很好得解决多bit信号异步传输的亚稳态问题。
不过在设计异步FIFO的时候要注意空满信号的产生、格雷码变换、深度选择(可参见笔试|面试|FPGA知识点大全系列(9)FIFO深度计算详解)等等。
相应的,在一些特定场合,数据突发长度只有2的情况下,FIFO的深度为2,此时异步FIFO就不需要使用格雷码计数了,因为计数信号只有1位,此时可用简化后的2深度FIFO进行跨时钟域传输。
③握手反馈机制
其实多bit信号传输的握手反馈机制,本质上和单bit类似,下图是一个握手反馈机制的框图:
源时钟域先将数据发送到总线上,并给出一个valid信号,而目标时钟域同步valid信号后,若valid信号为高电平则采样总线数据,并返回一个ready信号给源时钟域。源时钟域再次同步该ready信号,若ready信号为高,则代表一次握手成功,数据传输完毕,开始进行下一次数据传输。
采用握手机制可以保证异步multi-bit数据传输不出现错误,但由于需要等待握手的完成再传输数据,因此传输效率较低。
具体代码不搞了,搞不动了哈哈,以后实际项目中遇到再具体实现吧,可以参考下面列出的一些文章。
关于跨时钟域的传输相关问题,主流的大概就是这么多了,当然了,可能其他地方还有一些小方法,目前来看,掌握这些也差不多了。
本文参考:
https://www.cnblogs.com/IClearner/p/6485389.html
https://www.cnblogs.com/IClearner/p/6579754.html
https://blog.csdn.net/weixin_43727437/article/details/107110991
https://blog.csdn.net/u011075954/article/details/111974046
https://blog.csdn.net/Reborn_Lee/article/details/102877679
https://blog.csdn.net/weixin_44502896/article/details/106414998
https://blog.csdn.net/Reborn_Lee/article/details/101280171
https://blog.csdn.net/Reborn_Lee/article/details/89647526
https://blog.csdn.net/luoai_2666/article/details/119653178
https://blog.csdn.net/qq_38318540/article/details/107876042
本文参考:
微信关注“FPGA学习者”获取更多精彩内容
往期精彩
笔试|面试|FPGA知识点大全系列(1)
笔试|面试|FPGA知识点大全系列(2)
笔试|面试|FPGA知识点大全系列(3)
笔试|面试|FPGA知识点大全系列(4)
笔试|面试|FPGA知识点大全系列(5)
笔试|面试|FPGA知识点大全系列(6)
笔试|面试|FPGA知识点大全系列(7)之异步FIFO设计
笔试|面试|FPGA知识点大全系列(8)之时序分析
笔试|面试|FPGA知识点大全系列(9)FIFO深度计算详解
笔试|面试|FPGA知识点大全系列(10)跨时钟域问题大全解(上)