When to use it
When a stream has to cross from one clock domain to another, a plain register won't do: a multi-bit value sampled mid-change can be garbage. A dual-clock FIFO is the standard answer, the writer pushes on its clock, the reader pops on theirs, and the FIFO handles the crossing.
How it works
Two pointers walk a shared memory, one per clock. The clever part is that each pointer
is passed to the other domain as Gray code, so the synchronized value is only ever
off by one step, never a corrupt in-between. wfull and rempty are registered
comparisons of the local pointer against the synchronized remote one. (This is the
classic Cummings design.)
Gotchas
- The pointers must be Gray-coded and passed through a two-flop synchronizer, that's the whole reason this is safe. Don't shortcut it.
- Depth is 2^AW. Size it for the burst you need to absorb (see the FIFO depth calculator).
fullandremptyare deliberately conservative; they may lag by a clock, but they never lie in the dangerous direction.