`timescale 1ns/1ns
module data_driver(
input clk_a,
input rst_n,
input data_ack,
output reg [3:0]data,
output reg data_req
);
//1、对于发送端,data 输出需满足 data_req==1 ,且 data_req 需保持直到收到接收端回传的 data_ack,之后转低电平;
//2、data 循环 0-7 , 位宽为4, 需额外限制;变化时间点可选在收到回传 data_ack 时自加一
//3、接受到 data_ack 后需等待5个clk
//4、发送端需与接收端同步,选择 data_ack 的变化作为各项操作时机
//4、获取 data_ack 变化:【跨时钟域需打两拍消除亚稳态】
reg data_ack0,data_ack_flag;
always @ (posedge clk_a or negedge rst_n)
if (~rst_n) begin
data_ack0 <= 1'b0;
data_ack_flag <= 1'b0;
end else begin
data_ack0 <= data_ack;
data_ack_flag <= data_ack0;
end
//2、data 变化
always @ (posedge clk_a or negedge rst_n)
if (~rst_n) begin
data <= 3'd0;
end else if (data == 3'd7) begin
data <= 3'd0;
end else if (data_ack_flag) begin
data <= data + 1'b1;
end
//3、等待5个clk
reg [2:0] cnt;
always @ (posedge clk_a or negedge rst_n)
if (~rst_n) begin
cnt <= 3'd0;
end else if (data_ack_flag) begin
cnt <= 3'd0;
end else if (cnt == 3'd4) begin
cnt <= 3'd0;
end else begin
cnt <= cnt + 1'b1;
end
//4、发送
always @ (posedge clk_a or negedge rst_n)
if (~rst_n) begin
data_req <= 1'b0;
end else if (cnt == 3'd4) begin
data_req <= 1'b1;
end else if (data_ack_flag) begin
data_req <= 1'b0;
end
endmodule
module data_receiver(
input clk_b,
input rst_n,
input data,
output data_req,
output reg data_ack
);
//获取 data_req 变化
reg data_req0,data_req_flag;
always @ (posedge clk_b or negedge rst_n)
if (~rst_n) begin
data_req0 <= 1'b0;
data_req_flag <= 1'b0;
end else begin
data_req0 <= data_req;
data_req_flag <= data_req0;
end
// 发送 data_ack
always @ (posedge clk_b or negedge rst_n)
if (~rst_n) begin
data_ack <= 1'b0;
end else if (data_req_flag) begin
data_ack <= 1'b1;
end else begin
data_ack <= 1'b0;
end
endmodule

