格雷码 fifo 获取缓冲区中的元素数
Gray code fifo getting number of elements in buffer
我有 2 个不同的时钟,一个用于阅读,一个用于写作。我正在使用格雷码将指针与另外 2 个触发器同步,以便在输入信号的不同时钟上同步。
我看过的文章介绍了如何使用格雷码通过比较满状态的 2MSB 和空状态的相等来确定满信号和空信号。
但是,我需要获取缓冲区中元素的数量,而不仅仅是满信号或空信号。这可能与格雷码有关吗?
计算两个格雷码值之间差异的最容易理解的方法是将它们与公共时钟同步,将它们转换为二进制,然后对它们进行普通的二进制减法。虽然有可能设计一个完全组合的电路来计算两个格雷码值之间的差异,如果一个特定值的所有位都是稳定的,而另一个值中的一位发生变化,则只有一位输出中的 in 会发生变化,而所有其他的将保持稳定,这样的设计将比简单地同步两个计数器、转换为二进制并减去的设计复杂得多。
在评论中你询问了公共时钟并提到你的深度不是二的幂。
首先:编辑您的原始 post 并添加该问题和信息。
其次:在异步FIFO中没有公共时钟。写操作都是运行来自写时钟。读操作都是运行来自于读时钟。关键部分是在时钟域之间交换信息。这就是格雷码的用武之地。
第三:异步FIFO使用格雷码,因为一次只有一位改变。重要的是这个过程是循环的。因此,您的最后一个值和第一个值之间的差异也仅相差一位:
Counter Gray-code
000 000
001 001
010 011
011 010
100 110
101 111
110 101
111 100 <-- Last
000 000 <-- First again
当且仅当深度(以及计数器)是 2 的幂时,这才有效。因此,异步 FIFO always 的深度是 2 的幂。
如果您必须具有不同的深度,您可以将同步 FIFO 添加到开头或结尾。但是,如果您考虑一下:FIFO 只是一个弹性缓冲区。行为,例如16 个条目深度或 12 个条目没有什么不同,除此之外你有可能存储更多的值。
最后:正如supercat所说:你从二进制转换为格雷码,跨到另一个时钟域,然后再次将格雷码转换为二进制。
在结束时钟域中,您可以安全地比较读写计数器以确定 FIFO 的填充级别。
如果读取和写入端都需要该级别,则必须将此过程实施两次,每个时钟域一次。
我有 2 个不同的时钟,一个用于阅读,一个用于写作。我正在使用格雷码将指针与另外 2 个触发器同步,以便在输入信号的不同时钟上同步。
我看过的文章介绍了如何使用格雷码通过比较满状态的 2MSB 和空状态的相等来确定满信号和空信号。
但是,我需要获取缓冲区中元素的数量,而不仅仅是满信号或空信号。这可能与格雷码有关吗?
计算两个格雷码值之间差异的最容易理解的方法是将它们与公共时钟同步,将它们转换为二进制,然后对它们进行普通的二进制减法。虽然有可能设计一个完全组合的电路来计算两个格雷码值之间的差异,如果一个特定值的所有位都是稳定的,而另一个值中的一位发生变化,则只有一位输出中的 in 会发生变化,而所有其他的将保持稳定,这样的设计将比简单地同步两个计数器、转换为二进制并减去的设计复杂得多。
在评论中你询问了公共时钟并提到你的深度不是二的幂。
首先:编辑您的原始 post 并添加该问题和信息。
其次:在异步FIFO中没有公共时钟。写操作都是运行来自写时钟。读操作都是运行来自于读时钟。关键部分是在时钟域之间交换信息。这就是格雷码的用武之地。
第三:异步FIFO使用格雷码,因为一次只有一位改变。重要的是这个过程是循环的。因此,您的最后一个值和第一个值之间的差异也仅相差一位:
Counter Gray-code
000 000
001 001
010 011
011 010
100 110
101 111
110 101
111 100 <-- Last
000 000 <-- First again
当且仅当深度(以及计数器)是 2 的幂时,这才有效。因此,异步 FIFO always 的深度是 2 的幂。
如果您必须具有不同的深度,您可以将同步 FIFO 添加到开头或结尾。但是,如果您考虑一下:FIFO 只是一个弹性缓冲区。行为,例如16 个条目深度或 12 个条目没有什么不同,除此之外你有可能存储更多的值。
最后:正如supercat所说:你从二进制转换为格雷码,跨到另一个时钟域,然后再次将格雷码转换为二进制。
在结束时钟域中,您可以安全地比较读写计数器以确定 FIFO 的填充级别。
如果读取和写入端都需要该级别,则必须将此过程实施两次,每个时钟域一次。