В комментарии вы спрашиваете об общих часах и упоминаете, что ваша глубина не является степенью двойки.
Сначала: отредактируйте исходное сообщение и добавьте этот вопрос и информацию.
Второе: в синхронном 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
Это работает тогда и только тогда, когда глубина (и, следовательно, счетчики) являются степенью двойки. Поэтому a-синхронный FIFO всегда имеет глубину, которая является степенью двойки.
Если вы должны иметь другую глубину, вы можете добавить синхронный FIFO в начало или конец. Однако, если подумать: FIFO - это просто эластичный буфер. Поведение, если оно, например, Глубина 16 записей или 12 записей не отличаются, кроме того, что у вас есть потенциал для хранения большего количества значений.
Последнее: как сказал суперкат: вы преобразовываете двоичный код в код Грея, переходите в другой домен часов, а затем снова переводите код Грея в двоичный код.
В домене конечных часов вы можете безопасно сравнивать счетчики чтения и записи, чтобы определить уровень заполнения FIFO.
Если уровень необходим как на стороне чтения, так и на стороне записи, вы должны реализовать этот процесс дважды, по одному разу в каждом тактовом домене.