您的位置:首页 > 其它

跨时钟域设计【三】—— 数据同步

2015-03-31 08:55 267 查看
前面介绍了项目中用到的脉冲同步的基本方法,其基本功能是从某个时钟域取出一个单时钟宽度脉冲,然后在新的时钟域中建立另一个单时钟宽度的脉冲,但在实际应用中,需要同步的往往不止是脉冲信号,数据总线、地址总线和控制总线都有可能跨域传输。握手协议,RAM和FIFO是最基本的方法,但如果FPGA资源成为关键因素时,这些方法不一定是最好的方法。这里介绍另外一种方法——Toggle法(已经在项目中运用),适合快时钟域到慢时钟域传输数据。

假如Data是时钟域clkA(20MHz)的数据,需要同步到时钟域clkB(80MHz),我们可以在时钟域A产生一个Toggle信号,为clkA的2分频,然后把Toggle信号同步到clkB,并且在Toggle的上升沿和下降沿去捕获数据,这样能够保证Toggle信号的上升沿和下降沿采集到的是相邻的两个数据,并且数据不会丢失。该方法的Verilog HDL如下:

module DataSync(
input rst_n,
input clkA,
input clkB,
input [7:0] Data,


output reg [7:0] Data_sync
);


reg toggle;
reg toggle_d;
reg toggle_dd;
reg toggle_ddd;
wire toggle_edge;


always @ (posedge clkA or negedge rst_n)
if(!rst_n)
toggle <= 1'b0;
else
toggle <= ~toggle;

always @ (posedge clkB or negedge rst_n)
if(!rst_n)
begin
toggle_d <= 1'b0;
toggle_dd <= 1'b0;
toggle_ddd <= 1'b0;
end
else
begin
toggle_d <= toggle;
toggle_dd <= toggle_d;
toggle_ddd <= toggle_dd;
end

always @ (posedge clkB or negedge rst_n)
if(!rst_n)
Data_sync <= 8'h00;
else if(toggle_dd ^ toggle_ddd)
Data_sync <= Data;

endmodule
这种方法应用范围有限,实际应用中还得具体问题具体分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: