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

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

https://www.nowcoder.com/practice/2bf1b28a4e634d1ba447d3495134baac

//题设中考虑clk_a与clk_b频率不同但相差不大
`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_r1 ;
reg         data_ack_r2 ;
reg [2 :0]  bit_cnt     ;
reg [2 :0]  wait_cnt    ;

//data_ack_cross
always @(posedge clk_a or negedge rst_n)
begin
    if(!rst_n)
    begin
        data_ack_r1 <= 1'b0 ;
        data_ack_r2 <= 1'b0 ;
    end
    else 
    begin
        data_ack_r1 <= data_ack     ;
        data_ack_r2 <= data_ack_r1  ;
    end
end

//data
always @(posedge clk_a or negedge rst_n)
begin
    if(!rst_n)
        data <= 3'd0    ;
    else if(data == 4'd7)
        data <= 4'd0    ;
    else if(data_ack_r2)
        data <= data + 1'b1 ;
end

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

//wait_cnt
always @(posedge clk_a or negedge rst_n)
begin
    if(!rst_n)
        wait_cnt <= 3'd0    ;
    else if(data_req)
        wait_cnt <= 3'd0    ;
    else if(!data_req)
        wait_cnt <= wait_cnt + 1'b1 ;  
end

endmodule


/* -------------------------------- receiver -------------------------------- */
module data_receiver(
	input clk_b,
	input rst_n,
	input data_req,
	input wire [3:0]data,
	output reg data_ack
	);

//
reg     data_req_r1 ;
reg     data_req_r2 ;
reg [3 :0]  data_r  ;

//data_req_cross
always @(posedge clk_b or negedge rst_n)
begin
    if(!rst_n)
    begin
        data_req_r1  <= 1'b0 ;
        data_req_r2  <= 1'b0 ;
    end
    else
    begin
        data_req_r1  <= data_req    ;
        data_req_r2  <= data_req_r1 ;
    end
end

//data_r
always @(posedge clk_b or negedge rst_n )
begin
    if(!rst_n)
        data_r <= 4'd0  ;
    else if(data_req_r1)
        data_r <= data  ;
end

//data_ack
always @(posedge clk_b or negedge rst_n )
begin
    if(!rst_n)
        data_ack <= 1'b0    ;
    else if(data_req_r1)
        data_ack <= 1'b1    ;
    else
        data_ack <= 1'b0    ;
end
endmodule

全部评论

相关推荐

大叔叔1:你把自己说的话打码,所以你想表达什么
点赞 评论 收藏
分享
牛客316659795号:不是,证明hr初筛已经过了,要投给部门筛一遍
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务