题解 | #使用握手信号实现跨时钟域数据传输#
使用握手信号实现跨时钟域数据传输
https://www.nowcoder.com/practice/2bf1b28a4e634d1ba447d3495134baac
//题设中考虑clk_a与clk_b频率不同但相差不大 `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_r1 ; reg data_ack_r2 ; reg [2 :0] bit_cnt ; reg [2 :0] wait_cnt ; //data_ack_cross always @(posedge clk_a or negedge rst_n) begin if(!rst_n) begin data_ack_r1 <= 1'b0 ; data_ack_r2 <= 1'b0 ; end else begin data_ack_r1 <= data_ack ; data_ack_r2 <= data_ack_r1 ; end end //data always @(posedge clk_a or negedge rst_n) begin if(!rst_n) data <= 3'd0 ; else if(data == 4'd7) data <= 4'd0 ; else if(data_ack_r2) data <= data + 1'b1 ; end //data_req always @(posedge clk_a or negedge rst_n) begin if(!rst_n) data_req <= 1'b0 ; else if(wait_cnt == 3'd4) data_req <= 1'b1 ; else if(data_ack_r2) data_req <= 1'b0 ; end //wait_cnt always @(posedge clk_a or negedge rst_n) begin if(!rst_n) wait_cnt <= 3'd0 ; else if(data_req) wait_cnt <= 3'd0 ; else if(!data_req) wait_cnt <= wait_cnt + 1'b1 ; end endmodule /* -------------------------------- receiver -------------------------------- */ module data_receiver( input clk_b, input rst_n, input data_req, input wire [3:0]data, output reg data_ack ); // reg data_req_r1 ; reg data_req_r2 ; reg [3 :0] data_r ; //data_req_cross always @(posedge clk_b or negedge rst_n) begin if(!rst_n) begin data_req_r1 <= 1'b0 ; data_req_r2 <= 1'b0 ; end else begin data_req_r1 <= data_req ; data_req_r2 <= data_req_r1 ; end end //data_r always @(posedge clk_b or negedge rst_n ) begin if(!rst_n) data_r <= 4'd0 ; else if(data_req_r1) data_r <= data ; end //data_ack always @(posedge clk_b or negedge rst_n ) begin if(!rst_n) data_ack <= 1'b0 ; else if(data_req_r1) data_ack <= 1'b1 ; else data_ack <= 1'b0 ; end endmodule