题解 | #使用握手信号实现跨时钟域数据传输#
使用握手信号实现跨时钟域数据传输
https://www.nowcoder.com/practice/2bf1b28a4e634d1ba447d3495134baac
`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 [2:0] cnt;
reg ack_t0,ack_t1,ack_prest,ack_last;
always@(posedge clk_a or negedge rst_n) begin
if(~rst_n)begin
ack_t0<='b0;
ack_t1<='b0;
ack_prest<='b0;
ack_last<='b0;
end
else begin
ack_t0<=data_ack;
ack_t1<=ack_t0;
ack_prest<=ack_t1;
ack_last<=ack_prest;
end
end
always@(posedge clk_a or negedge rst_n) begin
if(~rst_n)begin
data_req<=3'b0;
data<=3'b0;
cnt<=3'b1;
end
else
if(ack_prest&&!ack_last) begin
data_req<='d0;
cnt<='d1;
data<=data+1'b1;
end
else if(cnt==3'b0)
data_req<=3'b1;
else begin
data_req<=1'b0;
cnt<=cnt+3'b1;
if(cnt==3'd5) begin
cnt<=3'b0;
data_req<='d1;
if(data==3'd7)
data<=3'b0;
end
end
end
endmodule
module data_receiver(
input clk_b,
input rst_n,
output reg data_ack,
input [3:0]data,
input data_req
);
reg [3:0]data_in_reg;
reg data_req_1, data_req_2;
always @ (posedge clk_b or negedge rst_n)
if (!rst_n) begin
data_req_1 <= 1'b0;
data_req_2 <= 1'b0;
end
else begin
data_req_1 <= data_req;
data_req_2 <= data_req_1;
end
always @ (posedge clk_b or negedge rst_n)
if (!rst_n) begin
data_ack <= 1'b0;
data_in_reg <= 4'b0;
end
else if (data_req_1 && !data_req_2) begin
data_ack <= 1'b1;
data_in_reg <= data;
end
else if (!data_req_2)
data_ack <= 1'b0;
else begin
data_ack <= data_ack;
data_in_reg <= data_in_reg;
end
endmodule
海康威视公司氛围 1020人发布