Medium · Memories & FIFOs · Parameterization & Generate
Design a synchronous FIFO (first-in, first-out queue) with a single clock, in show-ahead (also called "first-word fall-through") style: whenever the FIFO is not empty, dout already shows the oldest entry, and pop removes it.
| Parameter | Default | Meaning |
|---|---|---|
WIDTH | 8 | Data width in bits, WIDTH >= 1. |
DEPTH | 8 | Number of entries: a power of two, DEPTH >= 2. |
Your design must work for every legal combination: the hidden tests also instantiate it with non-default values, including the smallest legal ones. The examples use the defaults.
| Port | Dir | Width | Meaning |
|---|---|---|---|
clk | input | 1 | Clock. |
rst | input | 1 | Synchronous, active-high reset (takes effect only at a rising edge of clk). |
push | input | 1 | Write request: append din at the tail. |
din | input | WIDTH | Data to write. |
pop | input | 1 | Read request: remove the head entry. |
dout | output | WIDTH | The head (oldest) entry, valid whenever empty = 0. |
full | output | 1 | 1 when the FIFO holds DEPTH entries. |
empty | output | 1 | 1 when the FIFO holds 0 entries. |
count | output | $clog2(DEPTH)+1 | Number of entries, 0..DEPTH. |
All state changes happen at the rising edge of clk. At an edge with rst = 1, the FIFO becomes empty (count = 0, empty = 1, full = 0); stored data need not be cleared.
At an edge with rst = 0, let n be the number of entries before the edge:
push | pop | Condition | Effect |
|---|---|---|---|
| 0 | 0 | nothing | |
| 1 | 0 | n < DEPTH | din is appended; n + 1 entries |
| 1 | 0 | n == DEPTH (full) | ignored (data is dropped, nothing changes) |
| 0 | 1 | n > 0 | head entry removed; n − 1 entries |
| 0 | 1 | n == 0 (empty) | ignored |
| 1 | 1 | 0 < n | both happen: the head is removed and din appended; still n entries. This includes the full case (n == DEPTH): a push is accepted when a pop frees a slot at the same edge. |
| 1 | 1 | n == 0 (empty) | the pop is ignored and the push happens: 1 entry, dout = din after the edge |
Outputs depend only on the stored state: full, empty, count and (while the FIFO is not empty) dout reflect the FIFO contents after the most recent edge and must not depend combinationally on push, pop or din; they change only at a rising edge. In particular, after an edge that writes into an empty FIFO, dout shows that value immediately in the next cycle (no extra read latency), and after an edge that pops, dout shows the next entry. When empty = 1, the value of dout is not checked.
DEPTH = 8)| edge | push | din | pop | contents after the edge (head first) | dout | count | empty | full |
|---|---|---|---|---|---|---|---|---|
| 0 (rst) | x | x | x | – | – | 0 | 1 | 0 |
| 1 | 1 | A1 | 0 | A1 | A1 | 1 | 0 | 0 |
| 2 | 1 | B2 | 0 | A1 B2 | A1 | 2 | 0 | 0 |
| 3 | 1 | C3 | 1 | B2 C3 | B2 | 2 | 0 | 0 |
| 4 | 0 | x | 1 | C3 | C3 | 1 | 0 | 0 |
| 5 | 0 | x | 1 | – | – | 0 | 1 | 0 |
| 6 | 0 | x | 1 | – (ignored) | – | 0 | 1 | 0 |
| 7 | 1 | D4 | 1 | D4 (pop ignored) | D4 | 1 | 0 | 0 |
Sign up free to solve Synchronous FIFO (Show-Ahead) in your browser.