题解 | #使用握手信号实现跨时钟域数据传输#
使用握手信号实现跨时钟域数据传输
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