美文网首页
跨时钟域的处理方法(2)-数据的同步之握手协议

跨时钟域的处理方法(2)-数据的同步之握手协议

作者: 罐头说 | 来源:发表于2019-12-05 23:42 被阅读0次
    握手协议

    使用握手信号“xreq”和“yack”,“系统x”将数据发送给“系统y”。下面是使用握手信号传输数据的例子。

    1)     发送器“系统x”将数据放在数据总线上并发出“xreq”(请求)信号,表示有效数据已经发到接收器“系统y”的数据总线上。

    2)    采用两级D触发器缓存,把“xreq”信号同步到接收器的时钟域“yclk”上,得到“yreq2”信号,当采样到yreq2有效后,将数据锁存到系统y的总线上,同时接收器发出“yack”信号(相应信号)。

    3) 发送器接收到接收器发送来的“yack”信号,然后将“yack”信号同步到“xclk”时钟域上,同步的原理同上,采用两级的D触发器采样,采样时钟为“xclk”,得到同步后的“xack2”信号,xclk时钟采样到“xack2”有效后,发出下一个数据,同时让“xreq”有效一个时钟(xclk)。

    握手过程的时序图

    module  handshake_y(clky, rst_n_y, xdata, xreq, yack);

    input         clky;

    input         rst_n_y;

    input[7:0]     xdata;

    input         xreq;

    output        yack;

    reg[7:0]      ydata;

    reg yreq1, yreq2;

    always@(posedgeclky or negedge rst_n_y)

    begin

       if(!rst_n_y) yreq1 <= 1'b0;

       else       yreq1 <= xreq;

    end

    always@(posedgeclky or negedge rst_n_y)

    begin

       if(!rst_n_y) yreq2 <= 1'b0;

       else       yreq2 <= yreq1;

    end

    always@(posedgeclky or negedge rst_n_y)

    begin

       if(!rst_n_y)   ydata <= 8'h00;

       else if(yreq2) ydata <= xdata;

       else         ydata <= ydata;

    end

    always@(posedgeclky or negedge rst_n_y)

    begin

       if(!rst_n_y)   yack <= 1'b0;

       else if(yreq2) yack <= 1'b1;

       else        yack <= 1'b0;

    end

    endmodule

    //////////////////////////////////////////////////////////////////////////////////////

    module  handshake_x(clkx, yack, rst_n_x, xreq, xdata);

    input         clkx;

    input         yack;

    input         rst_n_x;

    output        xreq;

    output[7:0]    xdata;

    reg xack1,xack2;

    always@(posedgeclkx or negedge rst_n_x)

    begin

       if(!rst_n_x) xack1 <= 1'b0;

       else        xack1 <= yack;

    end

    always@(posedgeclkx or negedge rst_n_x)

    begin

       if(!rst_n_x) xack2 <= 1'b0;

       else        xack2 <= xack1;

    end

    always@(posedgeclkx or negedge rst_n_x)

    begin

       if(!rst_n_x)   data <= 8'h00;

       else if(xack2) data <= data + 1;

       else           data <= data;

    end

    always@(posedgeclkx or negedge rst_n_x)

    begin

       if(!rst_n_x)   xdata <= 8'h00;

       else if(xack2) xdata <= data;

       else           xdata <= xdata;

    end

    always@(posedgeclkx or negedge rst_n_x)

    begin

       if(!rst_n_x)   xreq <= 1'b0;

       else if(xack2) xreq <= 1'b1;

       else           xreq <= 1'b0;

    end

    endmodule

    ////////////////////////////////////////////////////////////////////////////

    module tb;

    regclkx;

    regclky;

    regrst_n_x;

    regrst_n_y;

    initial

    begin

    clkx =1'b0;

    clky =1'b0;

    rst_n_x= 1'b0;

    rst_n_y= 1'b0;

    # 100;

    rst_n_x= 1'b1;

    rst_n_y= 1'b1;

    end

    always#5 clkx = ~clkx;

    always#6 clky = ~clky;

    handshake_x  x1(  // transmiter

    .clkx(clkx),//in

    .yack(yack);//in

    .rst_n_x(rst_n_x);//in

    .xreq(xreq);//out

    .xdata(xdata);//out

    );

    handshake_y  y1( //receiver

    .clky(clky),//in

    .rst_n_y(rst_n_y),//in

    .xdata(xdata),//in

    .xreq(xreq),//in

    .yack(yack)//out

    );

    endmodule

    相关文章

      网友评论

          本文标题:跨时钟域的处理方法(2)-数据的同步之握手协议

          本文链接:https://www.haomeiwen.com/subject/oefsgctx.html