Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Digital Design & Verification (Verilog, SystemVerilog, VLSI)  Module 5 – Pipelines, handshakes, FIFOs and on-chip buses

Synchronous FIFOs and FIFO depth sizing

Build a synchronous FIFO with full, empty and almost-full flags, choose its read style, and size its depth from a burst and two rates, checked by simulation.

  • Intermediate
  • 20 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 7 of 20 minutes free
Free: A FIFO is a memory, two pointers and two flags · FIFO depth sizing counts the words that must wait. With a pass: 3 in-depth parts and 3 interview answers, about 13 minutes.

What you will learn

  • Build a synchronous FIFO whose pointers tell full from empty, with full, empty and almost-full flags
  • Choose between registered-output, first-word-fall-through and block-RAM FIFOs for a design
  • Size a FIFO from the burst length and the producer and consumer rates, and check the size by simulation
  • Verify a FIFO against a queue model with random traffic and assertions

Before you start

What you’ll learn · Before you start

What you will learn

  • Build a synchronous FIFO whose pointers tell full from empty, with full, empty and almost-full flags
  • Choose between registered-output, first-word-fall-through and block-RAM FIFOs for a design
  • Size a FIFO from the burst length and the producer and consumer rates, and check the size by simulation
  • Verify a FIFO against a queue model with random traffic and assertions

Before you start

On this page

A producer writes a burst of 64 words, one per clock cycle, into a FIFO whose consumer can take a word on only 4 cycles in 5. When the burst ends, 12.8 words, so at least 13, are still waiting, yet a FIFO whose full flag is read before each edge needs 14 entries: with 13 it lost a word in the simulation on this page.

You will build the pointers and flags of synchronous FIFOs, meet their three styles and size a FIFO from a burst and two rates, with a simulation that runs in your browser. Verilator 5.052, Icarus Verilog 13.0 and Yosys 0.69 ran and mapped the FIFOs.

A FIFO is a memory, two pointers and two flags

A synchronous FIFO: A first-in, first-out buffer whose write side and read side use the same clock: words leave in the order they came, and full and empty flags tell each side when to stop. keeps words in a small memory and gives them back in the order they came, first in, first out, with one clock for both sides. A write pointer says where the next word goes, a read pointer where the oldest one waits, and both wrap round to slot 0 after the last slot. Step through a ring of 4 slots filling up, refusing a word, wrapping round and draining:

Interactive · step through it A FIFO of 4 slots fills, refuses a word, wraps and drains front and rear move round a fixed set of slots and wrap from the last slot to slot 0.
Circular queue of 4 slots: 0: empty, 1: empty, 2: empty, 3: empty. front 0, rear 0, 0 in use.0123frontrearwraps around
  • being moved or written

Pseudo-code

  1. enqueue(x): if count = capacity: error "full"
  2. a[rear] ← x; rear ← (rear + 1) mod capacity; count ← count + 1
  3. dequeue(): if count = 0: error "empty"
  4. x ← a[front]; front ← (front + 1) mod capacity; count ← count − 1; return x

A circular queue with 4 slots. front is where the next item leaves, rear where the next one goes; both wrap around to slot 0 after slot 3.

When it finishes: 0 items queued.

Items 0
Operations 0

When the ring is full and when it is empty the two pointers point at the same slot, so a pointer alone cannot tell the two apart. The figure keeps a count. Synchronous FIFOs in RTL often give each pointer one bit more than an address needs instead. The low bits pick the slot and the top bit flips at every lap, so equal pointers mean empty, and equal slots on different laps mean full. For 8 entries the pointers have 4 bits:

Moment Write pointer Read pointer Slots Laps Flag
After reset 0000 0000 equal equal empty
3 words written 0011 0000 differ equal none
8 words written 1000 0000 equal differ full
All 8 read too 1000 1000 equal equal empty

An almost-full flag: A FIFO flag that rises while a set number of entries is still free, so that a producer that reacts a few cycles late can stop before the FIFO overflows. flag rises a few words before full, so a producer that reacts late still has room. FIFOs also differ in how they give words out: a registered-output FIFO shows a word one cycle after the read request, a first-word-fall-through FIFO shows the oldest word before any request, and a block-RAM FIFO keeps its memory in the FPGA’s RAM blocks, whose reads are clocked. Whatever the style, a FIFO is tested against a queue model that holds the same words.

Checkpoint

Check: Pointers, lap bits and flags

  1. Question 1 of 2 An 8-entry FIFO has 4-bit pointers. The write pointer is 1011 and the read pointer is 0011. What state is it in?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Full, because the slots (011) are equal and the lap bits differ

    The low three bits pick the slot and the top bit counts laps. Same slot, different laps: the writer has gone round once more than the reader, so the FIFO is full.

  2. Question 2 of 2 An 8-entry FIFO's write pointer is 1010 and its read pointer 0110. How many words does it hold?

    Type a number.

    A hint

    Subtract the pointers as 4-bit numbers.

    Show the answer: Question 2 of 2

    Answer: 4 words

    1010 is 10 and 0110 is 6, so the count is 10 − 6 = 4. The subtraction works across the wrap because both pointers count modulo 16, twice the depth.

FIFO depth sizing counts the words that must wait

FIFO depth sizing starts from the busiest moment: during a burst the FIFO must hold every word written that the consumer could not yet read. For the burst of 64 words, one per cycle, read on 4 cycles in 5, that is 64 − 64 × 4/5 = 12.8 words, so at least 13 entries. fifo_depth.py works the formula out, then runs the burst cycle by cycle into FIFOs of growing depth, with full and empty read before each edge as the RTL reads them. Press Run, then Edit:

The depth for one burst, by formula and by simulation Python · model/fifo_depth.py
"""How deep must a FIFO be for one burst? A producer writes BURST words, one at every cycle; the consumer can take a
word on READ_ON of every READ_OF cycles, whenever the FIFO holds one. The formula counts the words written during the
burst that the consumer could not read yet. The simulation runs the burst edge by edge into FIFOs of growing depth,
with full and empty read before each edge as the RTL reads them, and reports the first depth that loses nothing."""

import math

BURST = 64      # words in the burst, one written per cycle
READ_ON = 4     # the consumer reads on 4 ...
READ_OF = 5     # ... of every 5 cycles


def reads_on(cycle):
    """Whether the consumer can read at this cycle: the first READ_ON cycles of every READ_OF."""
    return cycle % READ_OF < READ_ON


def simulate(depth):
    """Runs the burst into a FIFO of this depth. A word written at one edge can be read at the next one at the
    earliest, and a write at an edge where the FIFO was full is refused. Returns (words lost, most words held)."""
    stored = most = lost = written = cycle = 0
    while written < BURST or stored:
        full, empty = stored == depth, stored == 0
        if reads_on(cycle) and not empty:   # the read side takes the oldest word
            stored -= 1
        if written < BURST:                 # the write side writes its next word, unless the FIFO was full
            if full:
                lost += 1
            else:
                stored += 1
            written += 1
        most = max(most, stored)
        cycle += 1
    return lost, most


waiting = BURST - BURST * READ_ON / READ_OF
print(f"burst of {BURST} words, one written per cycle, read on {READ_ON} of every {READ_OF} cycles")
print(f"formula: {BURST} - {BURST} x {READ_ON}/{READ_OF} = {waiting:g} words still waiting, so at least {math.ceil(waiting)} entries")
depth = 1
while True:
    lost, most = simulate(depth)
    if depth >= math.ceil(waiting) - 1:
        print(f"simulation: {depth} entries lose {lost} word{'' if lost == 1 else 's'}, at most {most} held")
    if lost == 0:
        break
    depth += 1
print(f"smallest depth that loses nothing: {depth}")

Output

burst of 64 words, one written per cycle, read on 4 of every 5 cycles
formula: 64 - 64 x 4/5 = 12.8 words still waiting, so at least 13 entries
simulation: 12 entries lose 2 words, at most 12 held
simulation: 13 entries lose 1 word, at most 13 held
simulation: 14 entries lose 0 words, at most 13 held
smallest depth that loses nothing: 14

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 fifo_depth.py

The simulation agrees that 13 words are the most ever waiting, yet the FIFO of 13 entries lost a word, and 14 was the smallest that lost none. At the edge where 13 words fill it, a read and a write come together: the read frees a slot, but the full flag was read before the edge, so the write is refused. A FIFO whose full flag lets a write through when a read happens at the same edge would manage with 13. That is why FIFO depth sizing ends with a simulation of the real flag timing, not with the formula alone.

Change the traffic

Press Edit and set READ_ON to 3: the formula rises to 25.6 words, and the simulation gives the depth to build.

Data Rate Converter (Mbps to MB/s) Turn a producer's and a consumer's data rates into the same unit before you compare them.

Key idea

A FIFO must hold every word written that the consumer could not read yet; the formula gives that number, and a simulation with the real flag timing gives the depth, here 14 for 13 words in waiting.

Checkpoint

Check: Sizing the depth for a burst

  1. Question 1 of 2 A burst of 100 words is written one per cycle, and the consumer reads on 3 cycles of every 4. By the formula, how many words are still waiting when the burst ends?

    Type a number.

    A hint

    Words written minus words read during the burst.

    Show the answer: Question 1 of 2

    Answer: 25 words

    100 − 100 × 3/4 = 25 words, so at least 25 entries; a simulation with the real flag timing then says whether the FIFO needs one more.

  2. Question 2 of 2 fifo_depth.py found 13 words at most waiting, yet the FIFO of 13 entries lost a word and 14 lost none. Why the extra entry?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: At the edge where 13 words filled it, a read and a write came together, and the full flag, read before the edge, refused the write

    A full flag read before the edge refuses a write even when a read at the same edge frees a slot. A FIFO whose full flag let such a write through would manage with 13 entries.

A FIFO in RTL, checked against a queue model Pro: opens with a Pro, Premium or Ultimate pass

sync_fifo.sv builds the pointers and flags of the table above. This part reads its RTL, runs it for 10,000 cycles against a queue model, and runs a copy whose pointers lost their lap bit.

In this part:

  • Pointers with a lap bit, and flags worked out from them
  • 10,000 random cycles against a queue model
  • Pointers without the lap bit cannot tell full from empty

1 runnable example (Commands, sync_fifo.sv, sync_fifo_bug.sv, tb_fifo.sv) · about 4 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Sizing with numbers: idle cycles, a late consumer and almost-full Pro: opens with a Pro, Premium or Ultimate pass

fifo_depth.py sized one burst. This part sizes three harder cases with numbers, each by the formula and by a simulation with the RTL’s flag timing, and finds the almost-full level that a producer who sees the flag late needs.

In this part:

  • Idle cycles on both sides: count the burst in cycles
  • A consumer that starts late: the depth its delay adds
  • Almost-full must leave room for the latency of backpressure
  • Your turn: the smallest depth that loses no word
  • Find the smallest FIFO depth that loses no word
    • Results of the sample tests

1 runnable example (Python) · 1 exercise with sample tests · about 5 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

Registered output, first-word fall-through and block RAM Pro: opens with a Pro, Premium or Ultimate pass

A FIFO’s read side comes in two timings, and only one of them is a block RAM’s clocked read as it stands. This part runs both side by side and shows what Yosys did to put the other in a block RAM all the same.

In this part:

  • A registered output gives the word one cycle after the read
  • A fall-through FIFO shows the head before the read
  • What block RAM cost each style on the iCE40

1 runnable example (Commands, fwft_fifo.sv, ram_table.py, tb_styles.sv) · about 4 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

Practise: pointers, flags and depth

Pointer flags and depth arithmetic come next, and the session leads with whichever of the two your past answers here found harder.

Practice that adapts to you

Practise this lesson

9 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 9 Why can a FIFO's two slot pointers alone not tell full from empty?

    Choose one answer.

    Show the answer: Question 1 of 9

    Answer: They point at the same slot both when the FIFO is full and when it is empty

    With slots alone, equal pointers happen at both ends. A count or one more bit on each pointer, the lap bit, tells the two cases apart.

  2. Question 2 of 9 How many bits does each pointer of a 16-entry FIFO need when it carries a lap bit?

    Type a number.

    A hint

    The slot needs $clog2 of the depth; the lap bit adds one.

    Show the answer: Question 2 of 9

    Answer: 5 bits

    16 slots need 4 address bits, and the lap bit makes 5. The pointers then count to 32 and wrap, twice the depth.

  3. Question 3 of 9 What is an almost-full flag for?

    Choose one answer.

    Show the answer: Question 3 of 9

    Answer: To tell a producer that reacts late to stop while there is still room for the words it sends meanwhile

    A producer that sees full one or more cycles late would overrun the FIFO. A flag that rises earlier gives it the room it needs while its reaction travels.

  4. Question 4 of 9 Which FIFO style shows the oldest word on its output before any read request?

    Choose one answer.

    Show the answer: Question 4 of 9

    Answer: First-word fall-through

    The styles differ in when the word appears: before the request for first-word fall-through, one cycle after it for a registered output, which is also how a block RAM reads.

  5. Question 5 of 9 A 16-entry FIFO keeps a count register instead of lap bits. Which width must the count have?

    Choose one answer.

    Show the answer: Question 5 of 9

    Answer: 5 bits, because the count must reach 16 itself

    Whatever tells full from empty must reach the depth itself. A count needs $clog2(DEPTH) + 1 bits, just as each pointer does with its lap bit.

  6. Question 6 of 9 What must a FIFO's depth cover during a burst?

    Choose one answer.

    Show the answer: Question 6 of 9

    Answer: Every word written that the consumer could not read yet

    Depth is the backlog at its worst: written minus read. The burst here wrote 64 and could read 51.2 in the same cycles, so 12.8 words waited.

  7. Question 7 of 9 A burst of 50 words is written one per cycle and read on every other cycle. By the formula, how many words wait at the end?

    Type a number.

    A hint

    Half of the cycles read.

    Show the answer: Question 7 of 9

    Answer: 25 words

    50 − 50 × 1/2 = 25 words wait, so at least 25 entries before the flag timing is considered.

  8. Question 8 of 9 A producer writes a word at every cycle and the consumer can read at every cycle. With full and empty read before each edge, as fifo_depth.py reads them, what is the smallest depth that loses no word?

    Type a number.

    A hint

    A word written at one edge can be read at the next one at the earliest.

    Show the answer: Question 8 of 9

    Answer: 2 entries

    One word is always waiting, written at one edge and read at the next. With one entry the FIFO is full at every edge, so the full flag read before the edge refuses each new word even though a read frees the slot; two entries lose nothing.

  9. Question 9 of 9 Why does depth sizing end with a simulation rather than with the formula?

    Choose one answer.

    Show the answer: Question 9 of 9

    Answer: The formula counts words, but the depth also depends on when the flags are read and when a read and a write meet

    A formula is the first estimate; a cycle simulation with the RTL's flag rules finds the corners it misses, such as a write refused at the edge where a read frees a slot.

Interview questions

Warm-up (fresher): how does a FIFO tell full from empty?

Full and empty both leave the write and read pointers on the same slot, so the slot alone cannot say which. Either keep a count of the words stored, full at the depth and empty at zero, or give each pointer one bit more than the address needs: that bit flips at every lap, so equal pointers mean empty and equal slots with different lap bits mean full. For 8 entries, write pointer 1000 against read pointer 0000 is full.

Three harder questions follow, on sizing a FIFO for a burst, on a FIFO that loses data once it fills, and on a fall-through FIFO in block RAM:

  1. Fresher to mid

    A block writes bursts of 96 words into a FIFO, one per cycle. The consumer reads on 3 cycles of every 4 and sees the first word 4 cycles after it is written; the producer stops on almost_full 2 cycles after the flag rises. What depth and almost-full level do you choose, and how do you check them?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to mid

    A 32-entry FIFO passes its block-level tests, which run at even read and write rates. In the system it corrupts data under heavy traffic, and a waveform shows empty rising while the FIFO should be full. What is the likely bug, and how do you fix both the FIFO and its tests?

    Model answer, Pro. First step and follow-ups

  3. Mid to senior

    A consumer is a valid/ready sink, so the FIFO in front of it must be first-word fall-through, yet the FIFO is 4,096 words deep and must use block RAM, whose read is clocked. How do you build it, and what does it cost?

    Model answer, Pro. First step and follow-ups

Flashcards · 6 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. Why can't a FIFO's read and write pointers alone tell full from empty?

    In both cases they point at the same slot. Keep a count, or give each pointer one extra bit that flips at every lap: equal pointers mean empty, equal slots on different laps mean full.

  2. With 4-bit pointers on an 8-entry FIFO, what do write pointer 1000 and read pointer 0000 mean?

    Full: the low three bits name the same slot and the lap bits differ.

  3. What is an almost-full flag for?

    It rises a few words before full, so a producer that reacts late still has room.

  4. How do registered-output, first-word-fall-through and block-RAM FIFOs give words out?

    A registered-output FIFO shows a word one cycle after the read request; a first-word-fall-through FIFO shows the oldest word before any request; a block-RAM FIFO keeps its words in RAM blocks whose reads are clocked.

  5. How many words wait when a 64-word burst, one word per cycle, meets a consumer that can read only 4 cycles out of 5?

    64 - 64 x 4/5 = 12.8, so the formula asks for at least 13 entries.

  6. Why did a FIFO of 13 entries still lose a word on that burst?

    At the edge where 13 words filled it a read and a write came together, but the full flag was read before the edge, so the write was refused. With that flag timing 14 entries were needed, which only the simulation showed.

Key takeaways

  • A FIFO is a memory with two pointers; with a lap bit on each, equal pointers mean empty and equal slots on different laps mean full.
  • An almost-full flag rises before full, so a producer that reacts late still has room.
  • The depth must hold every word the consumer could not read yet, and a simulation with the real flag timing gives it: 14 entries for the 13 words that waited here.

Terms in this lesson

almost-full flag
A FIFO flag that rises while a set number of entries is still free, so that a producer that reacts a few cycles late can stop before the FIFO overflows.
synchronous FIFO
A first-in, first-out buffer whose write side and read side use the same clock: words leave in the order they came, and full and empty flags tell each side when to stop.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.