在跨时钟域处理(一)中,我们介绍了针对单bit信号的跨时钟域处理方法—使用DFF打两拍,然而这个方法对多bit的数据并不管用。 首先,我们知道,使用DFF打两拍可以基本消除亚稳态的问题,但是无法保证采样得到的数据是正确的,因此,如果现在要采样的是一个多bit的跨时钟域信号,比如4bit信号,那么由于建立时间和保持时间的违例,虽然在打两拍之后可以得到一个稳定的数据,但该数据的每一个bit都不一定是正确的,所以其可能的值有 2 4 = 16 2^4=16 24=16种,这显然是无法接受的,因此,对于多比特信号的跨时钟域处理,不能照搬。 一种可以解决多bit跨时钟域信号传输的方法就是格雷码。
格雷码格雷码(又称循环码),它具有以下两个特点: 1、相邻的两个编码之间只有一位是不一样的。 2、当第N位从0变到1时,之后的数的N-1位会关于前半段对称,而比N位高的是相同的。 英文解释:
A Gray code is an encoding of numbers so that adjacent numbers have a single digit differing by 1
下图是格雷码和二进制码的一个对比 由于格雷码相邻数据只有一个bit不同,因此,在进行跨时钟域传输时,只有发生变化的那个bit有可能处于亚稳态,而其余bit由于保持不变,因此是稳定的,故多比特格雷码的跨时钟域传输相当于单比特信号的跨时钟域传输,我们采用打两拍的方法即可处理。
格雷码的产生是对二进制按位异或生成的,其RTL描述如下:
assign gray_code = (bnary >> 1) ^ bnary;
格雷码转二进制码
格雷码转换成二进制则需要对每位进行单独异或(以4bit为例):
Gray to Binary
b(3) = g(3)
b(2) = g(3) ^ g(2)
b(1) = g(3) ^ g(2) ^ g(1)
b(0) = g(3) ^ g(2) ^ g(1) ^ g(0)
RTL描述:
module gray2bin #(parameter WIDTH=4)
( input logic [WIDTH-1:0] gray,
output logic [WIDTH-1:0] bin
);
always_comb begin
for (int i=0 ; i> i);
end
end
endmodule
参考链接
https://zhuanlan.zhihu.com/p/149861619?from_voters_page=true https://zhuanlan.zhihu.com/p/161681621