使用握手信号“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
网友评论