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

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

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

全部评论

相关推荐

专业嗎喽:个人信息名字太大,合到电话邮箱那一栏就行,有党员写过党,剩下其他全删,站空太大了 把实习经历丰富,放最前面,然后是个人评价,技能之类的,然后是学校信息。项目经历最后面,可以就选一个自己擅长的。 现在是学校不是92就扣分的,没必要放前面。 然后现在看重实习经历>竞赛经历(校园经历)>课程项目经历
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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