`timescale 1ns/1ns
module data_driver(
input clk_a,
input rst_n,
input data_ack,
output reg [3:0]data,
output reg data_req
);
//=========================================================================\\
//*****************************define sinals*******************************\\
//=========================================================================\\
reg [2:0] cnt_wait ;
reg data_ack_r0 ;
reg data_ack_r1 ;
//=========================================================================\\
//*****************************main code***********************************\\
//=========================================================================\\
//data_ack 跨时钟域处理
always@(posedge clk_a or negedge rst_n)begin
if(!rst_n)begin
data_ack_r0 <= 1'b0 ;
data_ack_r1 <= 1'b0 ;
end
else begin
data_ack_r0 <= data_ack ;
data_ack_r1 <= data_ack_r0 ;
end
end
//data_req 边沿检测实现 数据请求信号的拉低 然后 通过等待5个时钟周期的cnt实现拉高
always@(posedge clk_a or negedge rst_n)begin
if(!rst_n)
data_req <= 1'b0 ;
else if(data_ack_r0 && !data_ack_r1)
data_req <= 1'b0 ;
else if(cnt_wait == 'd4 )
data_req <= 1'b1 ;
else
data_req <= data_req ;
end
//cnt_wait 只有在数据响应信号为低电平的时候才会进行计数,目的是计算等待的5个时间间隔
always@(posedge clk_a or negedge rst_n)begin
if(!rst_n)
cnt_wait <= 'd0 ;
else if(cnt_wait == 'd4)
cnt_wait <= 'd0 ;
else if(data_req == 'd0)
cnt_wait <= cnt_wait + 1'b1 ;
else
cnt_wait <= cnt_wait ;
end
//data
always@(posedge clk_a or negedge rst_n)begin
if(!rst_n)
data <= 'd0 ;
else if(data_ack_r0 && !data_ack_r1)
data <= data + 1'b1 ;
else
data <= data ;
end
endmodule
`timescale 1ns/1ns
module data_receiver(
input clk_b ,
input rst_n ,
input [3:0] data ,
input data_req ,
output reg data_ack
);
//=========================================================================\\
//*****************************define sinals*******************************\\
//=========================================================================\\
reg data_req_r0 ;
reg data_req_r1 ;
reg [3:0] data_reg ;
//=========================================================================\\
//*****************************main code***********************************\\
//=========================================================================\\
//data_req 输入信号需要打两拍进行跨时钟域处理
always@(posedge clk_b or negedge rst_n)begin
if(!rst_n)begin
data_req_r0 <= 1'b0 ;
data_req_r1 <= 1'b0 ;
end
else begin
data_req_r0 <= data_req ;
data_req_r1 <= data_req_r0 ;
end
end
//data_reg
always@(posedge clk_b or negedge rst_n)begin
if(!rst_n)
data_reg <= 'd0 ;
else if(data_req_r0 && !data_req_r1)
data_reg <= data ;
else
data_reg <= data_reg ;
end
//data_ack 通过上边沿检测实现响应信号ack的生成
always@(posedge clk_b or negedge rst_n)begin
if(!rst_n)
data_ack <= 1'b0 ;
else if(data_req_r0 && !data_req_r1)
data_ack <= 1'b1 ;
else
data_ack <= 1'b0 ;
end
endmodule

