题解 | #使用握手信号实现跨时钟域数据传输#
使用握手信号实现跨时钟域数据传输
https://www.nowcoder.com/practice/2bf1b28a4e634d1ba447d3495134baac
本题难度不算太大,需要注意的是计数以及握手信号的处理,sop信号以及eop信号的使用 `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_reg1; reg data_ack_reg2; wire data_sop; reg [2:0] cnt; //data_ack signal delay two timeperiod 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 //数据发送开始检测flag assign data_sop = (data_ack_reg1 && ~data_ack_reg2); always@(posedge clk_a or negedge rst_n) begin if(!rst_n) cnt <= 3'b0; else if(data_sop) cnt <= 3'b0; else cnt <= cnt + 1'b1; end //循环发送数据0-7 always@(posedge clk_a or negedge rst_n) begin if(!rst_n) data <= 4'b0; else begin if(data_sop) data <= data + 1'b1; else if(data == 4'd7) data <= 4'b0; else data <= data; end end //output data_req always@(posedge clk_a or negedge rst_n) begin if(!rst_n) data_req <= 1'b0; else if(cnt == 3'd4) data_req <= 1'b1; else if(data_sop == 1) data_req <= 1'b0; else data_req <= data_req; end endmodule //数据接收模块 module data_receiver( input clk_b, input rst_n, input [3:0] data, input data_req, output data_ack ); reg data_ack; reg data_req_reg1; reg data_req_reg2; wire data_eop; reg [3:0] data_in; 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 //数据接收检测flag assign data_eop = data_req_reg1 && ~data_req_reg2; always@(posedge clk_b or negedge rst_n) begin if(!rst_n) begin data_in <= 4'b0; data_ack <= 1'b0; end else if(data_eop) begin data_in <= data; data_ack <= 1'b1; end else begin data_in <= data_in; data_ack <= data_ack; end end endmodule


查看4道真题和解析