I read somewhere that some implementations of FIFOs have almost full and almost empty flags, the threshold for which can be set by any particular user. It was explained that a need for such flags arises: when you only have an empty signal, you can only use half of the clock cycles to read from the FIFO. In one clock cycle, you check that the FIFO is not empty, and in the other clock cycle you read from the FIFO. But when you have an almost empty flag and say the threshold for which is set to 16, you can read from the FIFO 16 words at a time with no issues.

My question is this: Why cant we just check that the FIFO is not empty and read from the FIFO in the same clock cycle? Do we run into some timing issues when we do this?

  • \$\begingroup\$ Most fifos I've used just have filling indicators, which seems to serve both this purpose and more general ones. \$\endgroup\$
    – DonFusili
    Jul 2, 2021 at 9:41
  • \$\begingroup\$ I've seen FIFO with empty, full and not empty flags. It very much depends on the chip. \$\endgroup\$
    – Damien
    Jul 2, 2021 at 9:48
  • \$\begingroup\$ I suspect FIFO can’t read and send status and write at the same time. \$\endgroup\$ Jul 2, 2021 at 11:34
  • 2
    \$\begingroup\$ In a typical FIFO, in a synchronous logic, you don't have to wait for not_empty to set, to assert dequeue signal. You can assert it in advance and then de-assert the dequeue signal when empty flag is set. In this way you read the first FIFO data in one cycle and saved an extra cycle. \$\endgroup\$
    – Mitu Raj
    Jul 2, 2021 at 13:12
  • 3
    \$\begingroup\$ Multiple reasons to use an almost-empty/almost-full threshold. One reason would be that you want to ensure there are N number of words in the FIFO before popping them out as a constant stream (no gap between clock cycles). Another reason is when a processor is trying to keep data in the FIFO at all times (continuous streaming), it needs a bit of advanced warning to setup a DMA transaction for the next burst of write-data. It's all application/architecture dependent. On some applications, I only need to use the empty and full flags, and completely ignore the almost-flags. \$\endgroup\$ Jul 2, 2021 at 18:38

2 Answers 2


The reasoning for using almost-empty and almost-full is to provide an ‘advance’ warning to the rest of the system that the limits of the FIFO are being reached. This gives the system more time to react and avoid over- or under-run conditions.

For example, a device writing a FIFO may take more than one cycle to respond to a full indication, so it could overrun. By giving an early warning with almost-full the host can see it in time, stall its writing and avoid FIFO overrun. In effect, the difference between almost-full and full forms a thing called a skid buffer. (The writer has ‘momentum’ and takes time to ‘skid’ to a stop, hence the name.)

One use of almost-empty is for the FIFO writer to know that it has to send fresh data soon before the reader fully drains the FIFO. Again, the advance warning allows the writer extra time, in this case to set up the next transfer to push some fresh data into the FIFO. This would be used for a data sink with no tolerance for stall, such as a DAC, that needs continuous data.

Another almost-empty use case is to compensate for read side response latency to the empty/not empty flag. Using almost-empty allows it more time to sample the flag and stall its reading in time to avoid reading the FIFO to underrun.

This seems to be related to the case you read about. That reader takes 1 cycle to respond to not-empty. Because of its sampling processing delay, it will read 'beyond the end' when the FIFO goes empty (that is, it will underrun) because it doesn't stop soon enough. So the dumb solution is for it to insert a ‘dead’ cycle in between each read to sample the empty flag before initiating the read.

Some protocols, like AXI-Stream, deal with this by qualifying the data with a valid flag. In this FIFO read case, not-empty is used as ‘valid’, so the reader doesn’t have to wait. Instead, it launches the read whenever it wants, but doesn’t actually forward the data unless its ‘ready’ and the FIFO ‘valid’ (not-empty) are both true.

Why would the system logic need extra latency time in the first place? It may have some architectural delay like a clock boundary cross to deal with, or there needs to be a pipeline inserted to help with timing closure.


Almost Empty (AE) and Almost Full (AF) flags allow the FIFO to support burst transfers and to trigger load/unload operations.

AE and AF flags can be designed into the FIFO chip or ASIC/PLD IP, otherwise extra logic circuitry can be added around the FIFO to do it.

For bursts: if the FIFO write data or read data is to be moved by burst transfer of blocks, such as across a bus in data packets, then the AE/AF thresholds can be set for when there is sufficient write space for a new incoming block or enough read data for a new outgoing block. Care must be taken if the total transfer is not a multiple of the block length, to ensure the stray end parts don't get ignored because the AE/AF flags have not tripped.

For load/unload: if it is preferable to fetch more FIFO write data or take out more FIFO read data all in one go, the AE/AF flags can be set to trigger the succession of single/burst transfers to do this. This may be because the supplier/consumer of the data does not want it drip-fed.

An example of loading is a digital sound playback card in a computer. It can be better for the fetching of more playback FIFO data from RAM to occur quickly once triggered. That notifies the software earlier that data is running low, giving it more advance time to load more data from mass storage. Actually fetching it may involve a series of successive bursts, or as close together as possible. But the whole fetching operation is triggered by a FIFO Almost Empty flag.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.