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

前面介绍了项目中用到的脉冲同步的基本方法,其基本功能是从某个时钟域取出一个单时钟宽度脉冲,然后在新的时钟域中建立另一个单时钟宽度的脉冲,但在实际应用中,需要同步的往往不止是脉冲信号,数据总线、地址总线和控制总线都有可能跨域传输。握手协议,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
 这种方法应用范围有限,实际应用中还得具体问题具体分析。 

posted @ 2015-03-31 08:55  hfyfpga  阅读(1580)  评论(0编辑  收藏  举报