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

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

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 d_data_ack;
	 reg d1_data_ack;
	 reg d2_data_ack;//两拍后的为了上升沿检测用
	 reg[2:0] cnt;
	 reg en;


always @(posedge clk_a)begin
	d_data_ack<=data_ack;
end

always @(posedge clk_a)begin
	d1_data_ack<=d_data_ack;
end


always @(posedge clk_a or negedge rst_n )begin
	if(!rst_n)
	      en<=0;
	else if({d1_data_ack,d_data_ack}==2'b01)
	      en<=1;
    else if(cnt==4)
	     en<=0;
end

always @(posedge clk_a or negedge rst_n )begin
	if(!rst_n)
	   cnt<=0;
	else if({d1_data_ack,d_data_ack}==2'b01)
	      cnt<=0;
	else if(cnt==4)
	    cnt<=0;
    else 
	cnt<=cnt+1;

end

always @(posedge clk_a or negedge rst_n )begin
	if(!rst_n)
	data_req<=0;
	else if({d1_data_ack,d_data_ack}==2'b01)
	data_req<=0;
	else if (cnt==4)
	data_req<=1;
	else 
	data_req<=data_req;

end

always @(posedge clk_a or negedge rst_n )begin
	if(!rst_n)
	data<=0;
	else if({d1_data_ack,d_data_ack}==2'b01)
	   if(data==7)
	     data<=0;
		 else
		 data<=data+1;
	else	
	 data<=data;
end

endmodule

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

	always@(posedge clk_b)begin
		d_data_req<=data_req;
	end

		always@(posedge clk_b)begin
		d1_data_req<=d_data_req;
	end 

	always@(posedge clk_b or negedge rst_n)begin
		if(!rst_n)
		 data_ack<=0;
		 else if({d1_data_req,d_data_req}==2'b01)
		 data_ack<=1;
		 else
		  data_ack<=0;
		 
	end

	always@(posedge clk_b or negedge rst_n)begin
		if(!rst_n)
		 receive_data<=0;
		 else if({d1_data_req,d_data_req}==2'b01)
		 receive_data<=data;
		 else
		  receive_data<= receive_data;
	end

endmodule


// module top(
// input clk_a,
// input clk_b,
// input rst_n,
// output [3:0]receive_data

// );
// wire data_ack;
// wire data_req;
// wire [3:0]data;

// data_driver uut(
// .clk_a(clk_a),
// .rst_n(rst_n),
// .data_ack(data_ack),
// .data_req(data_req),
// .data(data)

// );

// data_receiver aat(
// .clk_b(clk_b),
// .rst_n(rst_n),
// .data_ack(data_ack),
// .data_req(data_req),
// .data(data),
// .receive_data(receive_data)
// );

// endmodule

自己写的时候出了点问题,自己写的时候是在CNT+到4的时候才拉高req,cnt加到4又是用ack上升沿实现的,之前设计是让ack先到以后再加。这样出现的问题就是,第一次的时候ack没有识别到req无法拉高,而cnt无法到4 req不会拉高。一直会是0,因此一直计数,记到第一个4产生一个req给他一个初值,在检测到上升沿后cnt置0,重新计数,记到4时数据有效,req拉高发出

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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