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

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

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			data_ack_delay;
	reg			data_ack_delay_2;

	wire		data_ack_up_edge;

	always@(posedge clk_a or negedge rst_n)begin
		if(~rst_n)begin
			data_ack_delay<=1'b0;
			data_ack_delay_2<=1'b0;
		end
		else begin
			data_ack_delay<=data_ack;
			data_ack_delay_2<=data_ack_delay;
		end
	end

assign	data_ack_up_edge = data_ack_delay & ~data_ack_delay_2;

reg	[2:0]	data_cnt;



always@(posedge clk_a or negedge rst_n)begin
	if(~rst_n)begin
		data_cnt<=3'd0;
	end
	else if(data_ack_up_edge)begin
		data_cnt<=3'd0;
	end
	else if(data_req)begin
		data_cnt<=data_cnt;
	end
	else begin
		data_cnt<=data_cnt+1'b1;
	end
end

always@(posedge clk_a or negedge rst_n)begin
	if(~rst_n)begin
		data_req<=1'b0;
	end
	else if(data_cnt==3'd4)begin
			data_req<=1'b1;
	end
	else if(data_ack_up_edge)begin
			data_req<=1'b0;
	end
	else begin
		data_req<=data_req;
	end
end

always@(posedge clk_a or negedge rst_n)begin
	if(~rst_n)begin
		data<=4'd0;
	end
	else if(data_ack_up_edge)begin
		if(data==4'd7)
			data<=4'd0;
		else
			data<=data+1'b1;
	end
	else begin
		data<=data;
	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_temp;
	reg			data_req_delay;
	reg			data_req_delay_2;

	wire		data_req_up_edge;

	always@(posedge clk_b or negedge rst_n)begin
		if(~rst_n)begin
			data_req_delay<=1'b0;
			data_req_delay_2<=1'b0;
		end
		else begin
			data_req_delay<=data_ack;
			data_req_delay_2<=data_req_delay;
		end
	end

assign	data_req_up_edge = data_req_delay & ~data_req_delay_2;


always@(posedge clk_b or negedge rst_n)begin
	if(~rst_n)begin
		data_temp<=4'd0;
		data_ack<=1'b0;
	end
	else if(data_req_up_edge)begin
		data_temp<=data;
		data_ack<=1'b1;
	end
	else begin
		data_temp<=data_temp;
		data_ack<=1'b0;
	end
end
endmodule









首先搞懂一下握手信号的作用是什么?握手信号是用来处理数据在进行跨时钟域传输的时候进行的一种发送和应答信号。在上面题目中数据由快时钟域到慢时钟域传输的时候如果直接使用data数据线直接相连传输就会出现快时钟域数据丢失的问题。为了解决这样的问题就需要进行一种发送应答机制。

第二思考为什么叫握手信号。两个人进行握手的话肯定要有个人要先主动的去和对方握手,然后另外一个人在接收主动方的握手。所以这里的发送方就是主动的一方,他需要先把data_req信号进行驱动拉高。这里题目中说五个clock发送一次数据因此需要一个计数器。当计数器计数到五个clock的时候将data_req拉高。当data_req拉高之后说明此时数据传输开始,由于快时钟域数据发送的较快,数据发送到慢时钟域的时候需要等待慢时钟域捕获沿拉高,因此在data_req拉高之后需要发送的数据保持一段时间,当接收端接收到数据之后发出应答信号之后才表明当前的数据发送完成。一次握手进行完毕。

全部评论

相关推荐

黑皮白袜臭脚体育生:简历条例统一按使用了什么技术实现了什么功能解决了问题或提升了什么性能指标来写会好些,如使用布隆过滤器实现了判断短链接是否存在,大大提升了查询速度
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务