A synchronous FIFO stores an ordered stream when producer and consumer share one clock. It absorbs bursts, breaks timing paths, and converts short-term rate differences into occupancy.
The memory array is the easy part. Correctness lives in the acceptance rules, pointer wrap, full and empty flags, simultaneous push/pop behavior, and the exact cycle in which output data becomes valid.
A depth-five telemetry FIFO is the running design. Its non-power-of-two depth forces explicit pointer wrap, its registered output models a synchronous memory, and its conservative boundary policy remains unchanged from specification through scoreboard and assertions.
7 lessons, about 28 min
Seven. The central invariant is accepted pushes minus accepted pops. Requests refused at full or empty do not enter either count.
The whole topic on one page, taken from each lesson's Remember box. Read it before an interview, or print it.
Contract and Invariants
Count accepted operations, not request levels. A push seen at full is rejected, even if a pop happens on the same edge.
Conservation, bounds, ordering and pointer discipline are the four invariants.
With push and pop together, occupancy holds but both pointers still advance.
Rule of thumb: pointers and occupancy change on accepted operations only, never on raw requests.
Pointers, Occupancy and Flags
An extra wrap bit makes equal pointers mean empty, and equal address bits with different wrap bits mean full.
A counter gives exact occupancy and any depth, at the cost of an adder and a register.
For non-power-of-two depth, wrap explicitly at DEPTH-1. Truncating the pointer reaches nonexistent entries.
Portable Registered-Output FIFO
dout_valid_o marks the cycle of a newly removed word. The held bits afterwards mean nothing.
Never gate result-valid with !empty_o, because the final word is lost.
The memory array is never reset. Reset the pointers and the count, and empty hides the old contents.
Rule of thumb: treat the pop as a result pulse: reserve capacity before you ask, and capture every result.
Simultaneous Push and Pop
The conservative rule decides from the flags before the edge. It loses one opportunity at full and one at empty, and is portable.
The elastic rule accepts a push at full when a pop frees the slot. The memory must return the old word on a same-address collision.
Empty bypass is a different contract: it adds a combinational input-to-output path.
Rule of thumb: the acceptance policy is visible behaviour, so change it in the RTL, the scoreboard and the assertions together.
Standard vs Fall-Through Output
Direct fall-through reads the memory asynchronously. It suits a small flop-based queue, not a large synchronous SRAM.
A memory-friendly fall-through FIFO keeps an output register filled by a prefetch controller.
The consumer contract changes with the mode, so it is not a one-line output swap.
Rule of thumb: name the output mode in the interface or the module name.
Almost Flags and Parameter Edges
The margin must cover the cycles the producer needs to react, plus any register or crossing on the warning.
Test depths and margins at the limits: a one-bit width, depths of two and three, and a margin equal to the depth minus one.
Programmable watermarks are software policy. Almost flags are fixed hardware safety thresholds. Keep them separate.
Rule of thumb: derive each threshold from a real reaction latency, never from a habit.
Verification and Signoff
Compare every popped word with an independent ordered reference queue, and reach empty, full, simultaneous operations and several wraps.
Run the same top over a matrix of width, depth and margin. Illegal settings must fail at elaboration.
Reset discards queued words and any uncaptured result. A wrapper must account for them.
Rule of thumb: signoff is a scoreboard, boundary assertions, wrap-around traffic, a parameter matrix and the memory-inference report.
Mini project: a two-master bus with decoder, default slave and timeout
Practice question: Synchronous FIFO RTL design, blocking on full and empty
Code lab: Synchronous FIFO, 4 entries
Practice question: Synchronous FIFO with full and empty flags
Code lab: Synchronous FIFO, 8 entries
Practice question: FWFT FIFO with almost flags and pointer-distance occupancy
Interview: run a mock interview on this topic