verilog跨时钟域单bit信号转换

本文介绍了如何使用Verilog实现跨时钟域的数据同步,基于握手原理,通过两个时钟域下的req和ack信号进行同步。模块包含req信号的生成、采样以及ack信号的采样和dout信号的产生。测试代码展示了在不同时钟周期下,read信号的变化如何影响同步输出read_sync_pulse。
摘要由CSDN通过智能技术生成

基于握手原理的,网上很多,这里记录一下自己亲测试了能用的(知乎上看的,自己稍微改了一下,他那个原版跨大时钟域就用不了了

module handshake_sync ( 
    input clk1 , //快时钟信号
    input sys_rst_n , //复位信号,低电平有效
    input read , //信号,快时钟阈的
    input clk2 , //慢时钟信号

    output read_sync_pulse //输出信号
);

 //in1表示该信号在clk1时钟域
 reg req_in1 ;
 reg ack_in1 ;
 reg ack_in1_dly1 ;
 //in2表示该信号在clk2时钟域
 reg req_in2 ;
 reg req_in2_dly1 ;
 //*****************************************************
 //**                   main code
 //*****************************************************

 //1、clk1时钟域下req信号的生成
 always @(posedge clk1 or negedge sys_rst_n) begin
    if (sys_rst_n == 1'b0) 
        req_in1 <= 1'b0;
    else if(read == 1'b1)
        req_in1 <= 1'b1;
    else if(ack_in1_dly1 == 1'b1)
        req_in1 <= 1'b0;
    else
        req_in1 <= req_in1;
 end

 //2、clk2时钟域下req信号的采样
 always @(posedge clk2 or negedge sys_rst_n) begin
    if (sys_rst_n == 1'b0) begin
        req_in2 <= 1'b0;
        req_in2_dly1 <= 1'b0;
    end
    else begin
        req_in2 <= req_in1;
        req_in2_dly1 <= req_in2;
    end
 end

 //3、clk1时钟域下ack信号的采样 直接采样req_in2_dly1作为ack信号即可
 //这是因为有了req_in2和req_in2_dly1之后我们就可以生成dout,所以此时就可以返回ack信号了
 always @(posedge clk1 or negedge sys_rst_n) begin
    if (sys_rst_n == 1'b0) begin
        ack_in1 <= 1'b0;
        ack_in1_dly1 <= 1'b0;
    end

    else begin
        ack_in1 <= req_in2_dly1 ;
        ack_in1_dly1 <= ack_in1;
    end

 end

 //4、dout信号的产生

 assign read_sync_pulse = req_in2 & ~req_in2_dly1;

 endmodule

测试代码:

module TB();

reg sys_clk1; 
reg sys_clk2; 
reg sys_rst_n; 
reg read ;
wire read_sync_pulse;
initial begin
    sys_clk1 = 1'b0;
    sys_clk2 = 1'b0;
    sys_rst_n = 1'b0;

    read = 1'b0;

    #200
    sys_rst_n = 1'b1;

    #100
    read = 1'b1;
    #8
    read = 1'b0;
    #500
    read = 1'b1;
    #8
    read = 1'b0;

end

 always #4 sys_clk1 = ~sys_clk1;
 always #55.5 sys_clk2 = ~sys_clk2;

 handshake_sync u_handshake_sync(
    .clk1 (sys_clk1 ),
    .clk2 (sys_clk2 ),
    .sys_rst_n (sys_rst_n),
    .read (read ),
    .read_sync_pulse(read_sync_pulse )
 );

endmodule

仿真结果:

 

原作者文章链接:原文链接

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值