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

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

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拉高之后需要发送的数据保持一段时间,当接收端接收到数据之后发出应答信号之后才表明当前的数据发送完成。一次握手进行完毕。

全部评论

相关推荐

面试官全程关摄像头1.自我介绍一下2.React和Vue哪个更熟悉一点3.你在之前那段实习经历中有没有什么技术性的突破(我只是实习了44天工作28天,我把我能说的都说了)4.你封装的哪个表单组件支不支持动态传值5.自己在实习阶段Vue3项目封装过hook吗6.hook有什么作用7.Vue2和Vue3的响应式区别(我说一个是proxy是拦截所有的底层操作,Object.defineProperty本身就是一个底层操作,有些东西拦截不了,比如数组的一些操作还有等等,面试官就说实在要拦截能不能拦截????我心想肯定不行呀,他的底层机制就不允许吧)8.pinia和vuex的区别(这个回答不出来是我太久没用了)9.pinia和zustand的区别,怎么选(直接给我干懵了)(我说react能用pinia吗&nbsp;&nbsp;他说要用的话也可以)10.渲染一万条数据,怎么解决页面卡顿问题(我说分页、监听滚轮动态加载,纯数据展示好像还可以用canvas画)(估计是没说虚拟表单,感觉不满意)11.type和interface的区别12.ts的泛型有哪些作用(我就说了一个结构相同但是类型不同的时候可以用,比如请求响应的接口,每次的data不同,这里能用一个泛型,他问我还有什么)13.你项目用的是React,如果让你再写一遍你会选择什么14.pnpm、npm、yarn的区别15.dependencies和devdependencies的区别总而言之太久没面试了,上一段实习的面试js问了很多。结果这次js一点没问,网络方面也没考,表现得很一般,但是知道自己的问题了&nbsp;&nbsp;好好准备,等待明天的影石360和周四的腾讯了&nbsp;&nbsp;加油!!!
解zj:大三的第一段面试居然是这样的结局
查看15道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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