full and empty describe hard boundaries. almost_full and almost_empty warn a client early enough for its pipeline or scheduler to react.
Flag | Typical equation | Choose threshold from |
|---|---|---|
Almost full |
| Maximum writes already in flight after backpressure starts |
Almost empty |
| Reads or bursts already committed before the consumer can stop |
If a producer takes three cycles to observe almost-full and can issue one write per cycle, the margin needs at least three free entries, plus any implementation guard required by the interface.
For the depth-five telemetry FIFO, a two-entry almost-full margin prevents overflow only if at most two additional writes arrive after the warning. The margin only holds if the producer reacts in time, so an integration test must model the producer delay and in-flight writes: starting at count 3, two trailing writes reach 5 safely; a third is rejected by full and loses data unless the producer retains/retries it.
Read the row from the left: shaded slots hold data when the warning rises, dashed slots are what the margin keeps free.
The warning: with depth 5 and margin 2, almost_full rises when count reaches 3.
The margin: two writes already in flight land in slots 4 and 5, and the FIFO is exactly full.
The failure: a producer that reacts one cycle too late sends a third write. Full refuses it, and the word is lost unless the producer keeps it.
// snippet: threshold flags with guarded parameters
// Generate-if guards run at elaboration, so lint and synthesis see them too.
if (DEPTH < 2) begin : g_bad_depth
$error("DEPTH must be at least 2");
end
if (DW < 1) begin : g_bad_dw
$error("DW must be positive");
end
if (AF_MARGIN < 1 || AF_MARGIN > DEPTH) begin : g_bad_af
$error("AF_MARGIN must be in 1..DEPTH");
end
if (AE_MARGIN < 0 || AE_MARGIN >= DEPTH) begin : g_bad_ae
$error("AE_MARGIN must be in 0..DEPTH-1");
end
assign almost_full_o = (count >= DEPTH - AF_MARGIN);
assign almost_empty_o = (count <= AE_MARGIN);Configuration | Why it matters |
|---|---|
| Smallest useful queue stresses width and wrap expressions. |
| Proves explicit non-power-of-two pointer wrap. |
| Normal power-of-two implementation. |
| Catches zero-width slices and assumptions about byte data. |
Margins at minimum and maximum | Catches unsigned underflow and off-by-one threshold errors. |
Software-visible FIFOs often expose programmable high and low watermarks. Those are policy thresholds and may trigger interrupts. Hardware almost flags are usually fixed safety thresholds tied to pipeline reaction latency. Keep the two meanings separate even if both derive from occupancy.
At least four entries must remain when the warning is acted upon, plus any extra cycle introduced by registering or crossing the backpressure signal.
DEPTH = 3 in the parameter test matrix?It proves the pointers wrap explicitly at DEPTH-1. A design that relies on binary overflow will access index 3 before returning to zero.
The test bench for the depth-five FIFO checks the threshold arithmetic only. The producer's reaction time is not modelled there, so lossless behaviour has to be shown in an integration test with the real producer delay.