当前位置:   article > 正文

跨时钟域握手信号的实现(Verilog)_握手信号verilog

握手信号verilog

方法

使用握手信号是在两个不同域之间传输数据的有效方式,如下图所示:
在这里插入图片描述
使用握手信号xack和yreq,系统X发给系统Y,下面是使用握手信号传输数据的例子:
1)发送器系统X将数据放到数据总线上并发出xreq请求信号,表示有效数据已经发送到接收器系统Y的数据总线上
2)把xreq信号同步到接收器的时钟域yclk上。
3)接收器在识别xreq同步信号yreq2后,锁存数据总线上的信号
4)接收器发出确认信号yack,表示其已经接受了数据
5)接收器发出的yack信号同步到发送时钟xclk上
6)发送器在识别同步的ack信号后,将下一个数据放到数据总线上
握手信号的时序图如下所示:
在这里插入图片描述

握手信号的要求

数据应该在发送时钟域内稳定至少两个时钟上升沿,请求信号xreq的宽度应该超过两个上升沿时钟,否则从高速时钟的低速时钟域传递可能无法捕捉到该信号。缺点是是延迟太大(相比于FIFO)。

硬件实现

数据发送系统

模块框图如下
在这里插入图片描述

module tx_data(
    input   wire            tx_clk      ,
    input   wire            xack2       ,
    input   wire            rst_n       ,
    input   wire            en          ,

    output  reg             xreq        ,
    output  wire    [7:0]   t_data  
);

    reg     [3:0]       data1   ;
    reg     [3:0]       data2   ;

    //在yack2有效时data1和data2更新
    always @(posedge tx_clk or negedge rst_n) begin
        if(!rst_n) begin
            data1 <= 4'd1;
            data2 <= 4'd1;
        end
        else if(xack2) begin
            data1 <= data1 + 4'd1;
            data2 <= data2 + 4'd2;
        end
        else begin
            data1 <= data1;
            data2 <= data2;
        end
    end       

    //xreq信号
    always @(posedge tx_clk or negedge rst_n) begin
        if(!rst_n) begin
            xreq <= 1'b0;
        end
        else if(en) begin
            xreq <= 1'b1;
        end
        else if(xack2) begin
            xreq <= 1'b1;
        end
        else begin
            xreq <= 1'b0;
        end
    end

    assign t_data = {data1, data2};

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

数据接收系统

模块框图如下:
在这里插入图片描述

module rv_data(
    input   wire        rv_clk      ,
    input   wire        rst_n       ,
    input   wire        yreq2       ,
    input   wire [7:0]  r_data      ,

    output  reg         yack        ,
    output  wire [5:0]  result           
);
    /*
        接收到数据的第一周期进行数据计算
        第二周期返回ack信号
    */
    reg             dly1        ;
    reg     [5:0]   result_reg  ;

    always @(posedge rv_clk or negedge rst_n) begin
        if(!rst_n) begin
            yack <= 1'b0;
        end
        else if(dly1) begin
            yack <= 1'b1;
        end
        else begin
            yack <= 1'b0;
        end
    end

    always @(posedge rv_clk or negedge rst_n) begin
        if(!rst_n) begin
            dly1 <= 1'b0;
        end
        else if(yreq2) begin
            dly1 <= 1'b1;
        end
        else begin
            dly1 <= 1'b0;
        end
    end

    always @(posedge rv_clk or negedge rst_n) begin
        if(!rst_n) begin
            result_reg <= 'd0;
        end
        else if(yreq2) begin
            result_reg <= r_data[3:0] + r_data[7:4];
        end
        else begin
            result_reg <= result_reg;
        end
    end

    assign result = dly1 ? result_reg : 6'd0;

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

异步握手实现

模块框图如下:
在这里插入图片描述

module shake_hand_asy(
    input   wire            tx_clk      ,
    input   wire            rv_clk      ,
    input   wire            rst_n       ,
    input   wire            en          ,

    output  wire    [5:0]   result 
);

    wire                xreq    ;
    wire                yack    ;
    wire    [7:0]       data    ;

    reg                 yreq1   ;
    reg                 yreq2   ;
    reg                 xack1   ;
    reg                 xack2   ;

    //xreg的两级同步
    always @(posedge rv_clk or negedge rst_n) begin
        if(!rst_n) begin
            yreq1 <= 1'b0;
            yreq2 <= 1'b0;
        end
        else begin
            yreq1 <= xreq;
            yreq2 <= yreq1;
        end
    end

    //yack的两级同步
    always @(posedge tx_clk or rst_n) begin
        if(!rst_n) begin
            xack1 <= 1'b0;
            xack2 <= 1'b0;
        end
        else begin
            xack1 <= yack;
            xack2 <= xack1;
        end
    end

    tx_data u_tx_data(
    . tx_clk    (tx_clk)    ,
    . xack2     (xack2)     ,
    . rst_n     (rst_n)     ,
    . en        (en)        ,

    . xreq      (xreq)      ,
    . t_data    (data)
);

    rv_data u_rv_data(
     .rv_clk     (rv_clk)    ,
     .rst_n      (rst_n)     ,
     .yreq2      (yreq2)     ,
     .r_data     (data)      ,

     .yack       (yack)      ,
     .result     (result)      
);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

波形仿真

testbench代码如下:


`timescale  1ns/1ns

module tb_shake_hand_asy();

    reg         tx_clk      ;
    reg         rv_clk      ;
    reg         rst_n       ;
    reg         en          ;

    wire [5:0]  result      ;

    initial begin
        tx_clk = 1'b0;
        rv_clk = 1'b0;
        rst_n = 1'b0;
        en = 1'b0;
        #30
        rst_n = 1'b1;
        @(posedge tx_clk);
        en = 1'b1;          //启动
        @(posedge tx_clk);
        en = 1'b0;
    end

    always #15 tx_clk = ~tx_clk;
    always #10 rv_clk = ~rv_clk;

    shake_hand_asy u_shake_hand_asy(
    . tx_clk    (tx_clk)  ,
    . rv_clk    (rv_clk)  ,
    . rst_n     (rst_n)  ,
    . en        (en)  ,

    . result    (result)
);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

波形如下所示:
在这里插入图片描述
可知仿真正确。

总结

自己基础还很薄弱,继续加油!!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/206852
推荐阅读
相关标签
  

闽ICP备14008679号