题解 | #使用握手信号实现跨时钟域数据传输#

使用握手信号实现跨时钟域数据传输

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
	);
//data_ack上升沿
reg data_ack_reg1;
reg data_ack_reg2;

always@(posedge clk_a or negedge rst_n)
  if(!rst_n) begin
     data_ack_reg1 <=0;
	 data_ack_reg2 <=0;
  end
  else begin
	data_ack_reg1 <= data_ack;
	data_ack_reg2 <=data_ack_reg1;
  end

  //data_cnt
  reg [2:0]data_cnt;
  always@(posedge clk_a or negedge rst_n)
    if(!rst_n) 
	  data_cnt <= 0;
	else if(data_ack_reg1 && !data_ack_reg2)//data_ack上升沿,表示传输完成,开始计时
      data_cnt <= 0;//5个时钟:0,1,2,3,4
	else if(data_req)//data_req拉高,开始传数,保持不变
	  data_cnt <= data_cnt;
	else
	  data_cnt <= data_cnt + 1'b1;
 
 //data_req
 always@(posedge clk_a or negedge rst_n)
    if(!rst_n) 
	  data_req <= 0;
	else if(data_cnt == 3'd4)
	   data_req <= 1'b1;
	else if(data_ack_reg1 && !data_ack_reg2)
	   data_req <= 1'b0;
	else 
	   data_req <=  data_req;
	
	//data
always@(posedge clk_a or negedge rst_n)
    if(!rst_n) 
	  data <= 0;
	else if(data_ack_reg1 && !data_ack_reg2) begin
		if(data==4'd7) //发送0-7的循环数据
	      data <= 4'd0;
		else
		  data <=data + 1'b1;
	end	 
	else 
	   data <= data;
endmodule

//接收模块
`timescale 1ns/1ns
module data_receiver(
	input clk_b,
	input rst_n,
	input data_req,
	input [3:0]data,
	output reg  data_ack
	);
//data_req上升沿
reg data_req_reg1;
reg data_req_reg2;
always@(posedge clk_b or negedge rst_n)
  if(!rst_n) begin
     data_req_reg1 <=0;
	 data_req_reg2 <=0;
  end
  else begin
	data_req_reg1 <= data_ack;
	data_req_reg2 <=data_req_reg1;
  end

 //data_ack
 always@(posedge clk_b or negedge rst_n)
    if(!rst_n) 
	  data_ack <= 0;
	else if(data_req_reg1)
	   data_ack <= 1'b1;
	else 
	   data_ack <= 0;
	
	//data
	reg [3:0] data_in_reg;//接收数据
always@(posedge clk_b or negedge rst_n)
    if(!rst_n) 
	   data_in_reg <= 0; 
    //要检测上升沿而不是 高信号(会维持两个周期)
	else if(data_req_reg1 && !data_req_reg2) 
	   data_in_reg <= data;
	else 
	   data_in_reg <= data_in_reg;

endmodule

全部评论

相关推荐

11-04 19:05
已编辑
东莞城市学院 单片机
不知道怎么取名字_:你这个要实习两年?哪有这么久的,感觉就是即使你毕业了,但还按实习的话,是不是不用给你缴社保公积金啥的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务