You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First, thanks for you work, it's really a big time saver!
There's a problem with the way signals are synchronized between read and write clocks in the dual clock FIFO. The bit_synchronizer module is used for wraparound signals, while the handshake_synchronizer module is used for head and tail signals. This means it takes 2 clock cycles to synchronize the wraparound signals, while it may take much more cycles to synchronize the head and tail signals (because of the handshake procedure).
Since the synchronized version of the wraparound signals is used with the synchronized version of the head and tail signals in order to update the FIFO status signals, it may happen that a status flag is wrongly de-asserted because a synchronized wraparound signal changes too fast compared to the synchronized head and tail signals.
Take the following case for example:
This is a 16 words FIFO with rdclk period of 2.1 ns and a wrclk period of 9 ns. Read requests are made as soon as there are words available (Empty=0). Write requests are made every 3 wrclk cycles (provided Full=0).
At 452.55 ns, the synchronized head counter is updated. Head and tail read counters were equal before that, so the empty flag was set. This is not the case anymore, so the empty flag is reset. This triggers read requests, until all available words have been read (at 458.85 ns).
Meanwhile, at 455.5 ns, a write request is made. Since the head is at 15, it wraps around and is set to 0. This sets the wraparound write flag, which is synchronized a few read cycles later (at 458.85 ns).
The flag is actually processed a read cycle later (at 460.95 ns), when wraparound_rd changes. When this happens, the head and tail read counters are equal, because the head read counter has not been updated yet, so its value is not in sync with the wraparound read flag. This makes the read process believe that the FIFO is full, so there are words to be read, and the empty flag is reset. This triggers read requests, which produces invalid reads eventually.
I guess the solution to that is to make sure wraparound signals are synchronized along the head and tail signals, with a same handshake_synchronizer module.
BTW, the handshake_synchronizer is very slow and alternative solutions using gray counters (and bit_synchronizer modules) exist for dual clock FIFO which are faster yet safe.
The text was updated successfully, but these errors were encountered:
As I recall, when I wrote this I avoided Gray counters because there were active patents on them. They seem to be expired now so I will consider that in the next revision.
First, thanks for you work, it's really a big time saver!
There's a problem with the way signals are synchronized between read and write clocks in the dual clock FIFO. The
bit_synchronizer
module is used for wraparound signals, while thehandshake_synchronizer
module is used for head and tail signals. This means it takes 2 clock cycles to synchronize the wraparound signals, while it may take much more cycles to synchronize the head and tail signals (because of the handshake procedure).Since the synchronized version of the wraparound signals is used with the synchronized version of the head and tail signals in order to update the FIFO status signals, it may happen that a status flag is wrongly de-asserted because a synchronized wraparound signal changes too fast compared to the synchronized head and tail signals.
Take the following case for example:
This is a 16 words FIFO with rdclk period of 2.1 ns and a wrclk period of 9 ns. Read requests are made as soon as there are words available (
Empty=0
). Write requests are made every 3 wrclk cycles (providedFull=0
).At 452.55 ns, the synchronized head counter is updated. Head and tail read counters were equal before that, so the empty flag was set. This is not the case anymore, so the empty flag is reset. This triggers read requests, until all available words have been read (at 458.85 ns).
Meanwhile, at 455.5 ns, a write request is made. Since the head is at 15, it wraps around and is set to 0. This sets the wraparound write flag, which is synchronized a few read cycles later (at 458.85 ns).
The flag is actually processed a read cycle later (at 460.95 ns), when
wraparound_rd
changes. When this happens, the head and tail read counters are equal, because the head read counter has not been updated yet, so its value is not in sync with the wraparound read flag. This makes the read process believe that the FIFO is full, so there are words to be read, and the empty flag is reset. This triggers read requests, which produces invalid reads eventually.I guess the solution to that is to make sure wraparound signals are synchronized along the head and tail signals, with a same
handshake_synchronizer
module.BTW, the
handshake_synchronizer
is very slow and alternative solutions using gray counters (and bit_synchronizer modules) exist for dual clock FIFO which are faster yet safe.The text was updated successfully, but these errors were encountered: