If the sync FIFO has non-power-of-2 entries, for example, 3 entries, what can we do? Well, we have at least 2 approaches.
The easiest way is to maintain a counter for FIFO occupied entries, and use it to generate the FIFO empty or full condition.
The second approach is to use the same trick for pointer encoding as what we see in power-of-2-entry FIFO. For example, both read and write pointers have (2 + 1) bits, where 2 is for bits to index 3-entry FIFO, and 1 is to decode FIFO full and empty conditions. Pointer value change shall have the following patterns:
000 -> 001 -> 010 -> 100 -> 101 -> 110 -> 000 -> …
When read pointer is equal to write pointer, the FIFO is empty; When read pointer is the same as write pointer other than MSB, the FIFO is full.