Part 8 explained why an async FIFO is hard to get right. This part asks the verification question directly: if this design were subtly broken, what would that look like, and how would a testbench actually notice?
The core functional claim
Strip everything else away, and a FIFO makes one promise: data comes out in exactly the order it went in, with nothing lost, nothing duplicated, and nothing corrupted — for any legal sequence of writes and reads, at any relative speed between the two clocks. Every check in the plan below exists to stress some way that promise could quietly fail.
What specifically needs to be checked
- Data integrity and ordering. Every value read out must match the value written, in the same order it was written — the most direct way to catch a pointer or memory-addressing bug.
fullis asserted exactly when it should be. Never late (which would let a write corrupt data that hasn't been read yet) and never early (which would needlessly block a legal write).emptyis asserted exactly when it should be. Same idea in reverse — never late (allowing a bogus read of stale data) and never early (blocking a legal read).- Writes while full, and reads while empty, are handled safely. Depending on the spec, this DUT might ignore the write/read attempt, or it might be the testbench's job to simply never issue one — either way, this needs to be a deliberate, checked decision, not an assumption.
- Behavior holds across every clock-ratio regime. Write clock much faster than read clock, read clock much faster than write clock, equal frequencies with a random phase offset, and a clock ratio that changes mid-test. The synchronizer logic from Part 8 is exactly what's being stressed here — get this wrong, and it typically only shows up under one specific, uncommon ratio.
- Back-to-back and boundary operations. Simultaneous write and read on the same cycle, a write on the exact cycle the FIFO becomes full, a read on the exact cycle it becomes empty, filling completely and draining completely, and doing that wrap-around more than once so the extra pointer bit from Part 8 actually gets exercised.
- Reset behavior. Both domains typically have independent resets. What should happen if one side resets while the other is mid-transaction? The spec should define this, and the testbench should check the DUT actually does it.
Choosing directed vs. constrained-random for this DUT
Recall Part 3's distinction. For an async FIFO, the practical answer is both: a handful of directed tests for the boundary cases above that are easy to name but easy for random stimulus to miss by chance (exact full, exact empty, back-to-back at the boundary), plus a constrained-random test that randomizes data values, write/read timing, and — critically — the relationship between the two clock periods, run for enough seeds that the clock-ratio corner cases in the list above get hit by chance, repeatedly.
Deciding what the scoreboard is allowed to look at
This is the black-box vs. white-box decision from Part 3, made concrete. A fully black-box scoreboard only ever sees what the write and read interfaces show it: it can push every written value into its own reference queue and pop-and-compare against every read value, which is enough to catch every data-integrity and ordering bug in the list above without knowing anything about internal pointers. The one thing a black-box scoreboard can't directly explain is why a full/empty-flag-timing bug happened — for that, most real projects allow a white-box assertion or checker with visibility into the internal Gray-coded pointers, purely as a debug aid, kept separate from the pass/fail scoreboard itself.
Takeaway
A verification plan for this DUT is really one core claim — correct, lossless, in-order data — checked from every angle a real chip could hit it: every clock-ratio regime, every full/empty boundary, and every reset scenario. Deciding this on paper first is what turns "we ran some tests" into "we know what we tested and why."
Part 10 turns this exact plan into a working UVM environment — the driver, monitor, and scoreboard that actually run these checks.