跨时钟域的处理方法(2)-数据的同步之握手协议

握手协议

使用握手信号“xreq”和“yack”,“系统x”将数据发送给“系统y”。下面是使用握手信号传输数据的例子。

1)     发送器“系统x”将数据放在数据总线上并发出“xreq”(请求)信号,表示有效数据已经发到接收器“系统y”的数据总线上。

2)    采用两级D触发器缓存,把“xreq”信号同步到接收器的时钟域“yclk”上,得到“yreq2”信号,当采样到yreq2有效后,将数据锁存到系统y的总线上,同时接收器发出“yack”信号(相应信号)。

3) 发送器接收到接收器发送来的“yack”信号,然后将“yack”信号同步到“xclk”时钟域上,同步的原理同上,采用两级的D触发器采样,采样时钟为“xclk”,得到同步后的“xack2”信号,xclk时钟采样到“xack2”有效后,发出下一个数据,同时让“xreq”有效一个时钟(xclk)。

握手过程的时序图

module  handshake_y(clky, rst_n_y, xdata, xreq, yack);

input         clky;

input         rst_n_y;

input[7:0]     xdata;

input         xreq;

output        yack;

reg[7:0]      ydata;

reg yreq1, yreq2;

always@(posedgeclky or negedge rst_n_y)

begin

   if(!rst_n_y) yreq1 <= 1'b0;

   else       yreq1 <= xreq;

end

always@(posedgeclky or negedge rst_n_y)

begin

   if(!rst_n_y) yreq2 <= 1'b0;

   else       yreq2 <= yreq1;

end

always@(posedgeclky or negedge rst_n_y)

begin

   if(!rst_n_y)   ydata <= 8'h00;

   else if(yreq2) ydata <= xdata;

   else         ydata <= ydata;

end

always@(posedgeclky or negedge rst_n_y)

begin

   if(!rst_n_y)   yack <= 1'b0;

   else if(yreq2) yack <= 1'b1;

   else        yack <= 1'b0;

end

endmodule

//////////////////////////////////////////////////////////////////////////////////////

module  handshake_x(clkx, yack, rst_n_x, xreq, xdata);

input         clkx;

input         yack;

input         rst_n_x;

output        xreq;

output[7:0]    xdata;

reg xack1,xack2;

always@(posedgeclkx or negedge rst_n_x)

begin

   if(!rst_n_x) xack1 <= 1'b0;

   else        xack1 <= yack;

end

always@(posedgeclkx or negedge rst_n_x)

begin

   if(!rst_n_x) xack2 <= 1'b0;

   else        xack2 <= xack1;

end

always@(posedgeclkx or negedge rst_n_x)

begin

   if(!rst_n_x)   data <= 8'h00;

   else if(xack2) data <= data + 1;

   else           data <= data;

end

always@(posedgeclkx or negedge rst_n_x)

begin

   if(!rst_n_x)   xdata <= 8'h00;

   else if(xack2) xdata <= data;

   else           xdata <= xdata;

end

always@(posedgeclkx or negedge rst_n_x)

begin

   if(!rst_n_x)   xreq <= 1'b0;

   else if(xack2) xreq <= 1'b1;

   else           xreq <= 1'b0;

end

endmodule

////////////////////////////////////////////////////////////////////////////

module tb;

regclkx;

regclky;

regrst_n_x;

regrst_n_y;


initial

begin

clkx =1'b0;

clky =1'b0;

rst_n_x= 1'b0;

rst_n_y= 1'b0;

# 100;

rst_n_x= 1'b1;

rst_n_y= 1'b1;

end

always#5 clkx = ~clkx;

always#6 clky = ~clky;


handshake_x  x1(  // transmiter

.clkx(clkx),//in

.yack(yack);//in

.rst_n_x(rst_n_x);//in

.xreq(xreq);//out

.xdata(xdata);//out

);

handshake_y  y1( //receiver

.clky(clky),//in

.rst_n_y(rst_n_y),//in

.xdata(xdata),//in

.xreq(xreq),//in

.yack(yack)//out

);

endmodule

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容