题解 | #使用握手信号实现跨时钟域数据传输#
使用握手信号实现跨时钟域数据传输
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 data_ack_reg1,data_ack_reg2; always @(posedge clk_a or negedge rst_n) begin if(~rst_n) begin cnt <= 0; end else if(data_ack_reg1 & (~data_ack_reg2)) begin cnt <= 0; end else if(cnt <= 5) begin cnt <= cnt + 1; end end always @(posedge clk_a or negedge rst_n) begin if(~rst_n) begin data_ack_reg1 <= 1'b0; data_ack_reg2 <= 1'b0; end else begin data_ack_reg1 <= data_ack; data_ack_reg2 <= data_ack_reg1; end end always @(posedge clk_a or negedge rst_n) begin if(~rst_n) begin data <= 0; end else if(data_ack_reg1 & (~data_ack_reg2)) begin if(data >= 7) data <= 0; else data <= data + 1; end end always @(posedge clk_a or negedge rst_n) begin if(~rst_n) begin data_req <= 1'b0; end else if(cnt == 4) begin data_req <= 1'b1; end else if(data_ack_reg1 & (~data_ack_reg2)) begin data_req <= 1'b0; end end endmodule module data_receiver( input clk_b, input rst_n, input [3:0] data, input data_req, output reg data_ack ); reg [3:0] data_reg; reg data_req_reg1; reg data_req_reg2; always @(posedge clk_b or negedge rst_n) begin if(~rst_n) begin data_req_reg1 <= 1'b0; data_req_reg2 <= 1'b0; end else begin data_req_reg1 <= data_req; data_req_reg2 <= data_req_reg1; end end always @(posedge clk_b or negedge rst_n) begin if(~rst_n) begin data_reg <= 0; end else if(data_req_reg1 & (~data_req_reg2)) begin data_reg <= data; end end always @(posedge clk_b or negedge rst_n) begin if(~rst_n) begin data_ack <= 1'b0; end else if(data_req_reg1 & (~data_req_reg2)) begin data_ack <= 1'b1; end else begin data_ack <= 1'b0; end end endmodule
这题重要的是要对data_ack和data_req打一拍之后再用来做判断用,这也是握手能进行多bit跨时钟域传输的原因——将多bit跨时钟域传输转换为单bit跨时钟域传输的问题。

查看14道真题和解析