数据打两拍后(d0_r, d1_r)才能使用(d1_r),要制造脉冲信号不能使用d0_r,因为大概率还会有亚稳态,得再延一个周期得到d2_r,用d1_r和d2_r制造脉冲
`timescale 1ns/1ns
module data_driver(
input clk_a,
input rst_n,
input data_ack,
output reg [3:0]data,
output reg data_req
);
reg data_ack_d0_r;
reg data_ack_d1_r;
reg data_ack_d2_r;
always @(posedge clk_a or negedge rst_n) begin
if (!rst_n) begin
data_ack_d0_r <= 'd0;
data_ack_d1_r <= 'd0;
data_ack_d2_r <= 'd0;
end
else begin
data_ack_d0_r <= data_ack;
data_ack_d1_r <= data_ack_d0_r;
data_ack_d2_r <= data_ack_d1_r;
end
end
always @(posedge clk_a or negedge rst_n) begin
if (!rst_n) begin
data <= 'd0;
end
else if (data_ack_d1_r & !data_ack_d2_r) begin
data <= data == 'd7 ? 'd0 : data + 'd1;
end
end
reg [3-1:0] cnt_r;
always @(posedge clk_a or negedge rst_n) begin
if (!rst_n) begin
cnt_r <= 'd0;
end
else if (data_ack_d1_r & !data_ack_d2_r) begin
cnt_r <= 'd0;
end
else if (data_req) begin
cnt_r <= cnt_r;
end
else begin
cnt_r <= cnt_r + 'd1;
end
end
always @(posedge clk_a or negedge rst_n) begin
if (!rst_n) begin
data_req <= 'd0;
end
else if (data_ack_d1_r) begin
data_req <= 'd0;
end
else if (cnt_r == 'd4) begin
data_req <= 'd1;
end
end
endmodule
module data_receiver(
input clk_b,
input rst_n,
input [3:0]data,
input data_req,
output reg data_ack
);
reg data_req_d0_r;
reg data_req_d1_r;
reg data_r;
always @(posedge clk_b or negedge rst_n) begin
if (!rst_n) begin
data_req_d0_r <= 'd0;
data_req_d1_r <= 'd0;
end
else begin
data_req_d0_r <= data_req;
data_req_d1_r <= data_req_d0_r;
end
end
always @(posedge clk_b or negedge rst_n) begin
if (!rst_n) begin
data_r <= 'd0;
data_ack <= 'd0;
end
else if (data_req_d1_r) begin
data_r <= data;
data_ack <= 'd1;
end
else begin
data_ack <= 'd0;
end
end
endmodule