跨时钟域之全握手

在跨时钟域(Clock Domain Crossing,CDC)处理时,需要根据源时钟频率,目的时钟频率以及数据是多bit还是单bit数据来选择合适的同步方式。本文主要介绍全握手与半握手处理机制。握手的机制是基于反馈信号进行跨时钟域同步。接下来会详细分析半握手与全握手机制,总结两种握手机制的特点以及适用的场景。

假设有跨时钟域传输的电路如图 1所示,在图中分为trans_module与recv_module两个模块,其中trans_module为发起传输请求的模块,recv_module会根据trans_module的请求来响应传输。

1 跨时钟域传输模块电路图

跨时钟域握手传输的时序图如图 2所示。具体传输过程如下:

  1. trans_module将数据准备完毕,将WDATA1输出到twrdata写数据线,并且拉高trans_req,发起一次传输请求。
  2. recv_module通过第一级D触发器(也成同步器,Synchronizer)对trans_req进行同步得到tready_ff1,再经过第二级同步器得到tready_ff2。
  3. 此时recv_module采样到(tready_ff2 == true)因此recv_module可认为twrdata数据已经准备好能够对twrdata传输的数据进行采样得到WDATA1
  4. recv_module可能根据功能计算出要回写的数据,并将要写的数据通过rwrdata数据线发送,此时拉高rack,用于通知trans_module已经成功接收到数据或者要回写的数据已经准备好了。至此已经完成了半握手。
  5. trans_module通过同步器同步recv_module发送过来的rack信号得到rcv_ack_ff2信号,当检测到(rcv_ack_ff2 == true)此时trans_module知道recv_module已经成功收到数据,并且回写的数据已经准备好了,能够对rwrdata数据线采样得到RDATA1。
  6. 将trans_req拉低,表示trans_module已经接收到recv_module回写的数据。
  7. recv_module采集经过同步器同步的tready_ff2为低时拉低rack信号,此时recv_module知道trans_module已经成功接收到回写的数据
  8. trans_module检测到rcv_ack_ff2为低电平,此时本次传输已经结束,能够进行下一轮传输。即根据需求重新发起trans_req

 

 

2 跨时钟域握手机制时序图

 

为进一步验证上述理论,分别仿真快时钟域向慢时钟域发起传输请求与慢时钟域向快时钟域发起传输请求的全握手传输实验。结果如图 3图 4所示,从波形图中能看到数据均被正确传输。

3 慢时钟域向快时钟域传输

 

4 快时钟域向慢时钟域传输

 

 

问题讨论:

  1. 图 2中展示的时慢时钟域到块时钟域传输的过程,那么当快时钟域向慢时钟域进行数据传输时,握手的方法仍然适用吗?

为了详细说明快时钟域向慢时钟域传输数据,根据握手传输的机制能够得到如图 5所示时序图。从图中能够明显发现全握手方式不论是快时钟域到慢时钟域还是慢时钟域到块时钟域均能够处理跨时钟域问题

5 快时钟域向慢时钟域同步

 

  1. 当传输过程描述中e)阶段已经trans_module已经成功将数据写入到recv_module,并且已经接收到recv_module回写的数据,此时能否进行下一轮新的传输?

如果传输时情况是慢时钟域发起trans_req请求,那么当trans_module采集到rcv_ack_ff2为高拉低trans_req一个时钟周期后就可以进行下一轮请求,不必等到rcv_ack_ff2为低。但是当传输时快时钟域发起trans_req的情况如果trans_module不等待rcv_ack_ff2为低就发起新的请求就可能存在trans_req拉低被recv_module漏采,因此需要根据实际情况选择传输方式。

本问题能够进一步讨论半握手方式与全握手方式。半握手方式适用于慢时钟域向快时钟域发起trans_req请求的情况,半握手传输效率比较高,能够比较快的完成数据传输的握手操作,但是半握手是单向的数据传输,当需要回写数据时,应该采用全握手,或者回写数据方作为半握手传输的发起方。对于快时钟域向慢时钟域发起trans_req,或者两个时钟域时钟速度完全不确定的情况下适合全握手方式。

 

别走开,Jayden小哥哥有话说,仿真工程与源码可扫描二维码关注公众号鼓捣猫尼回复“全握手工程源码”获得(不要引号)。在Jayden小哥哥的杂货铺会不定期的更新关于PFGAIC设计、模拟电路、嵌入式编程等学习心得,期待小伙伴的关注与点赞,I need U

双向握手是一种常用的接口协议,用于在两个模块之间进行数据传输。在Verilog中,双向握手通常使用valid和ready信号来实现。其中,valid信号表示数据的有效性,ready信号表示模块是否准备好接收数据。当valid和ready信号同时为高电平时,数据传输才会进行。 下面是一个Verilog模块的例子,演示了如何使用valid和ready信号实现双向握手: ```verilog module handshake( input clk, input rst_n, input [7:0] data_in, input valid_a, input ready_b, output ready_a, output reg valid_b, output reg [9:0] data_out ); reg [1:0] state; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= 2'b00; valid_b <= 1'b0; data_out <= 10'b0; end else begin case (state) 2'b00: begin // 等待输入数据 if (valid_a && ready_b) begin state <= 2'b01; data_out <= data_in; valid_b <= 1'b1; end end 2'b01: begin // 等待确认信号 if (valid_a && ready_b) begin state <= 2'b10; data_out <= data_out + data_in; valid_b <= 1'b1; end end 2'b10: begin // 等待输出数据 if (valid_a && ready_b) begin state <= 2'b00; valid_b <= 1'b0; end end endcase end end assign ready_a = (state == 2'b00); endmodule ``` 在这个例子中,模块接收到输入数据后,会等待确认信号,然后将输入数据累加到输出数据中。当输出数据准备好后,模块会等待下游模块的准备信号,然后将数据发送给下游模块。如果下游模块没有准备好,模块会一直等待,直到下游模块准备好为止。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值