FPGA跨时钟域设计的一点总结

时间:2022-12-20 23:45:25
1. 亚稳态的概念说明
是指 触发器无法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚稳态引时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平上。在这个稳定期间,触发器输出一些中间级电平,或者可能处于振荡状态,并且这种无用的输出电平可以沿信号通道上的各个触发器级联式传播下去。

同步系统中,如果触发器的setup time / hold time不满足,就可能产生亚稳态,此时触发器输出端Q在有效时钟沿之后比较长的一段时间处于不确定的状态,在这段时间里Q端毛刺、振荡、固定的某一电压值,而不是等于数据输入端D的值。这段时间称为决断时间(resolution time)。经过resolution time之后Q端将稳定到0或1上,但是究竟是0还是1,是随机的,与输入没有必然的关系。

在跨时钟域的设计中,由于时钟的不同步,及其容易产生亚稳态。
FPGA跨时钟域设计的一点总结

常用的同步方法是使用两级寄存器来进行同步:
FPGA跨时钟域设计的一点总结

2. 多时钟设计的命名规则
不同时钟域的时钟和模块以及模块输入输出信号命名,应当加上适当的前缀以区分。如控制部分uclk,视频处理部分vclk,NVM接口部分mclk。这样既便于区分,也便于在后端做时序约束和分析时的处理(比如某些命令的批量处理,set_false_path -from { u* })。

3. 多时钟设计的模块划分
将整体的多时钟设计分割成多个单个独立时钟的功能模块和负责模块间同步的同步模块,这样非常利于后端的时序分析,程序结构也更加清晰。

4. 快时钟域到慢时钟域的同步
常见问题:快时钟域的信号持续时间太短,慢时钟域采不到
FPGA跨时钟域设计的一点总结

解决方法1: 将快时钟域传递的信号持续时间延长,使其大于慢时钟域的一个时钟周期。
FPGA跨时钟域设计的一点总结

解决方法2:使用握手信号(反馈信号)
FPGA跨时钟域设计的一点总结

5. 跨时钟域传递多个相关信号(如enable和load信号)
5.1 问题1: 传递两个同时需要的信号(b_load和b_en)
FPGA跨时钟域设计的一点总结

解决方法:只传递一个信号(b_lden)
FPGA跨时钟域设计的一点总结

5.2 问题2:传递两个前后顺序控制的信号(ben1和ben2)
FPGA跨时钟域设计的一点总结

解决方法:只传递一个信号(ben1)
FPGA跨时钟域设计的一点总结

5.3 问题3:传递两个编码控制信号(bdec[0]和bdec[1])
FPGA跨时钟域设计的一点总结

解决方法1:产生一个ready信号(bden_n)来指示数据的有效性
FPGA跨时钟域设计的一点总结

解决方法2:使用one-hot key信号结合状态机来处理接收到的信号
FPGA跨时钟域设计的一点总结
Note

6. 数据的同步
There are far too many opportunities for multi-bit data changes to be incorrectly sampled using synchronizers.

6.1 握手信号(但是要牺牲一定的时间)
Data can be passed between clock domains using two or three handshake control signals, depending on the application and the paranoia of the design engineer. The biggest disadvantage to using handshaking is the latency required to pass and recognize all of the handshaking signals for each data word that is transferred.

For many open-ended data-passing applications, a simple two-line handshaking sequence is sufficient. The sender places data onto a data bus and then synchronizes a "data_valid" signal to the receiving clock domain. When the "data_valid" signal is recognized in the new clock domain, the receiver clocks the data into a register in the new clock domain (the data should have been stable for at least two rising clock edges in the sending clock domain) and then passes an " acknowledge" signal through a synchronizer to the sender. When the sender recognizes the synchronized "acknowledge" signal, the sender can change the value being driven onto the data bus.

Under some circumstances, it might be useful to use a third control signal, "ready", sent through a synchronizer from the receiver to the sender to indicate that the receiver is indeed "ready" to receive data. The "ready" signal should not be asserted while the "data_valid" signal is true. When the "data_valid" signal is de-asserted, a "ready" signal can be passed to the sender. Of course, with the added handshake signal comes the penalty of longer latency to synchronize and recognize the third control signal.

6.2 FIFO
One of the most popular methods of passing data between clock domains is to use a FIFO. A dual port memory is used for the FIFO storage. One port is controlled by the sender which puts data into the memory as fast a one data word (or one data bit for serial applications) per write clock. The other port is controlled by the receiver, which pulls data out of memory one data word per read clock. Two control signals are used to indicate if the FIFO is empty, full or partially full. Two additional control signals are frequently used to indicate if the FIFO is almost full or almost empty.

In theory, placing data into a shared memory with one clock and removing the data from the shared memory with another clock seems like an easy and ideal solution to passing data between clock domains. For the most part it is, but generating accurate full and empty flags can be challenging.


==============================================================
附录(相关设计技巧):
1. 慢时钟域到快时钟域的同步及上升(下降)沿检测电路
同步和上升沿检测电路:(注意输入B是被反向过的)
FPGA跨时钟域设计的一点总结

时序图
FPGA跨时钟域设计的一点总结
代码实现为:先将发送时钟域过来的信号用寄存器打两拍,然后将输出信号A和再打一拍的反向信号B相与(如果是 下降沿检测,则将输出信号A反向和再打一拍的同向信号B相与)。

拓展:如果将先将发送时钟域过来的信号用寄存器打两拍,然后将输出信号A和再打一拍的信号B相一或,就得到的是 上升沿和下降沿都检测的逻辑。

2. 脉冲检测(将脉冲信号转换为电平信号,pulse-toggle-circuit)
基本电路为:
FPGA跨时钟域设计的一点总结

时序图:
FPGA跨时钟域设计的一点总结

代码实现为:
always@(posedge clk1 or negedge nrst)
begin
if(!nrst)
Q <= 0;
else 
Q <= D;
end

assign D = Data ? Q_bar : Q;

拓展:。。。

3. 完整握手流程
完整握手流程为:
FPGA跨时钟域设计的一点总结

时序图:
FPGA跨时钟域设计的一点总结

代码实现为:


4. 部分握手流程I(完整握手流程的简化版) 
部分握手流程I为:
FPGA跨时钟域设计的一点总结

时序图:
FPGA跨时钟域设计的一点总结

说明:省去了完整握手流程里面的最后一步,也就是ACK信号自动会把自己de-assert,而不是要等检测到REQ信号de-assert之后了。

In the first partial handshake scheme, Circuit A asserts its request signal and the Circuit B acknowledges it with a single clock-wide pulse. In this case, Circuit B does not care when Circuit A drops its request signal. However, to make this technique work, Circuit A must drop its request signal for at least one clock cycle otherwise Circuit B cannot distinguish between the previous and the new request.(A发出的REQ信号必须至少无效持续一个时钟周期,否则B无法辨别两个响铃的REQ信号)

With this handshake, Circuit B uses a level synchronizer for the request signal and Circuit A uses a pulse synchronizer for the acknowledge signal. In this handshake protocol the acknowledge pulses only occur when Circuit B detects the request signal. This allows Circuit A to control the spacing of the pulses into the synchronizer by controlling the timing of its request signal.

5. 部分握手流程II(完整握手流程的简化版)
部分握手流程II为:
FPGA跨时钟域设计的一点总结

时序图:
FPGA跨时钟域设计的一点总结

说明: 省去了完整握手流程里面的最后两步,两个信号在assert保持一段时间以后都是自动de-assert,不在相互检测。

In this second partial handshake scheme, Circuit A asserts it request with asingle clock-wide pulse and Circuit B acknowledges it with a single clock-wide pulse. In this case, both circuits need to save state to indicate that the request is pending.

This type of handshake uses pulse synchronizers butif one circuit has a clock that is twice as fast as the other, that circuit can use an edge-detect synchronizer instead. (如果有一个时钟域的时钟比另外一个时钟域的时钟快两倍以上,则可以使用边沿检测同步电路来代替握手电路)

6. Basic Data Path Design
基本电路为:
FPGA跨时钟域设计的一点总结

时序图:
FPGA跨时钟域设计的一点总结

FPGA跨时钟域设计的一点总结

说明:A design using full handshake signaling has a large window of time for the receiving circuit to sample the signal bus and is  not very efficient. The same design can use a partial handshake instead of the full handshake tospeed up the transfer.

7. Advanced Data Path Design
基本电路为:


时序图:


代码实现为: