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

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

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_d0_r;
	reg data_ack_d1_r;
	reg data_ack_d2_r;
	always@(posedge clk_a or negedge rst_n)
	begin
		if(!rst_n)
		begin
		data_ack_d0_r <= 1'b0;
		data_ack_d1_r <= 1'b0;
		data_ack_d2_r <= 1'b0;
		end
		else
		begin
		data_ack_d0_r <= data_ack;
		data_ack_d1_r <= data_ack_d0_r;
		data_ack_d2_r <= data_ack_d1_r;			
		end
	end

	always@(posedge clk_a or negedge rst_n)
	begin
		if(!rst_n)
		data <= 4'd0;
		else if(data_ack_d1_r & !data_ack_d2_r)
		data <= data == 4'd7? 4'd0 : data + 4'd1;
	end

	reg [2:0] cnt_r;
	always@(posedge clk_a or negedge rst_n)
	begin
		if(!rst_n)
		cnt_r <= 3'd0;
		else if(data_ack_d1_r & !data_ack_d2_r)
		cnt_r <= 3'd0;
		else if(data_req)
		cnt_r <= cnt_r;
		else
		cnt_r <= cnt_r + 3'd1;
	end

	always@(posedge clk_a or negedge rst_n)
	begin
		if(!rst_n)
		data_req <= 1'b0;
		else if(data_ack_d1_r)
		data_req <= 1'b0;
		else if(cnt_r == 3'd4)
		data_req <= 1'b1;
		else
		data_req <= data_req;
	end


endmodule


module data_receiver(
	input clk_b,
	input rst_n,
	input [3:0]data,
	input data_req,
	output reg data_ack
	);

	reg data_req_d0_r;
	reg data_req_d1_r;
	always@(posedge clk_b or negedge rst_n)
	begin
		if(!rst_n)
		begin
		data_req_d0_r <= 1'd0;
		data_req_d1_r <= 1'd0;
		end
		else
		begin
		data_req_d0_r <= data_req;
		data_req_d1_r <= data_req_d0_r;
		end 
	end	

	reg [3:0] data_r;
	always@(posedge clk_b or negedge rst_n)
	begin
		if(!rst_n)
		begin
			data_r <= 4'd0;
			data_ack <= 1'd0;
		end
		else if(data_req_d1_r)
		begin
			data_r <= data;
			data_ack <= 1'd1;
		end
		else
		begin
			data_r <= 4'd0;
			data_ack <= 1'd0;
		end

	end

endmodule

全部评论

相关推荐

05-10 16:48
门头沟学院 Java
程序员小白条:主要原因,投递太晚了,快手应该早点溜了,你都从去年9月开始的,半年也差不多3月跑路了,这样的话,至少有5个以上的面试机会
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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