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

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

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 [2:0] cnt;
	reg ack_t0,ack_t1,ack_prest,ack_last;

always@(posedge clk_a or negedge rst_n) begin
	if(~rst_n)begin
		ack_t0<='b0;
		ack_t1<='b0;
		ack_prest<='b0;
		ack_last<='b0;
	end
	else begin
		ack_t0<=data_ack;
		ack_t1<=ack_t0;
		ack_prest<=ack_t1;
		ack_last<=ack_prest;
	end
end


always@(posedge clk_a or negedge rst_n) begin
	if(~rst_n)begin
		data_req<=3'b0;
		data<=3'b0;
		cnt<=3'b1;
	end
	else
		if(ack_prest&&!ack_last) begin
			data_req<='d0;
			cnt<='d1;
			data<=data+1'b1;
			end
		else if(cnt==3'b0)
			data_req<=3'b1;
		else begin
			data_req<=1'b0;
			cnt<=cnt+3'b1;
			if(cnt==3'd5) begin
				cnt<=3'b0;
				data_req<='d1;
				if(data==3'd7)
					data<=3'b0;
			end
		end
end
endmodule


module data_receiver(
    input clk_b,
    input rst_n,
    output reg data_ack,
    input [3:0]data,
    input data_req
    );
    reg [3:0]data_in_reg;
    reg data_req_1, data_req_2;
     
    always @ (posedge clk_b or negedge rst_n)
        if (!rst_n) begin
            data_req_1 <= 1'b0;
            data_req_2 <= 1'b0;
        end
        else begin
            data_req_1 <= data_req;
            data_req_2 <= data_req_1;
        end

  
    always @ (posedge clk_b or negedge rst_n)
        if (!rst_n) begin
            data_ack <= 1'b0;
            data_in_reg <= 4'b0;
        end
        else if (data_req_1 && !data_req_2) begin
            data_ack <= 1'b1;
            data_in_reg <= data;
        end
				else if (!data_req_2)
						data_ack <= 1'b0;
        else begin
            data_ack <= data_ack;
            data_in_reg <= data_in_reg;
        end
     
endmodule

全部评论

相关推荐

01-17 12:35
吉首大学 Java
秋招之BrianGriffin:自己的工作自己做!😡
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务