Predict every FIFO read from a queue of accepted writes, and check each response one edge after its read.
Hardware context: Independent monitor and scoreboard for registered-read FIFO outputs. Check accepted FIFO reads against an independent expected-value queue.
The scoreboard is where the testbench decides pass or fail. The monitor reports, for every rising edge, which write and read the FIFO accepted and what read_valid and read_data showed. Because read data is registered, the response seen at an edge belongs to the read accepted one edge earlier.
Write the method observe of fifo_scoreboard. Keep the written data in expected, oldest first. At each edge, first check the response against the read pending from the previous edge, then record this edge’s accepted read and write.
Return 0 for a correct edge, or a code: 1 for a response nobody asked for, 2 for a missing response, 3 for wrong data. Count every error. On a reset edge the FIFO empties: check the response as usual, then forget every expected entry and the pending read.
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
edges | 8 | input of each check |
Full specification
class fifo_scoreboard;
bit [7:0] expected[$]; // written and not yet read, oldest first
bit pending; // a read was accepted at the previous edge
bit [7:0] pending_data; // the data that read must return
int errors;
function int observe(bit reset, bit write_acc, bit [7:0] write_data, bit read_acc, bit read_valid, bit [7:0] read_data);
endclass
| At each edge, in this order | |
|---|---|
| 1. Check the response | read_valid and read_data answer the read accepted at the previous edge. Return 1 for read_valid with no read pending, 2 for a pending read with read_valid low, 3 for wrong read_data; otherwise 0. Count every nonzero code in errors. |
| 2. Record the read | pending = read_acc. An accepted read takes the oldest expected entry into pending_data. |
| 3. Record the write | An accepted write appends write_data to expected. |
Each case feeds one monitor trace into a fresh fifo_scoreboard and reports errors, the first code and the edge (from 1) where it came, the entries left in expected and whether a read is pending. The traces come from a depth-3 FIFO; some have one planted response fault. An accepted read never comes with expected empty.
reset = 1 marks a reset edge. The monitor reports no accepted read or write on it. After step 3, a reset edge empties expected and clears pending.
Examples
Example 1
A clean run- Input
edges (X reset, W accepted write + data, R accepted read, v read_valid + read_data): 1:Wa7 2:R 3:W71 va7 4:R 5:X v71 6:W0b 7:X 8:W46 9:R 10:X v46 11:Wc8 12:Waf 13:-
- Output
errors = 0, first_error = none (0), entries_left = 2, read_pending = no
Every response matches the oldest entry, one edge after its read: no errors.
Example 2
A response that never comes- Input
edges (X reset, W accepted write + data, R accepted read, v read_valid + read_data): 1:Wa7 2:- 3:W71 4:Wd4 5:R 6:W46 va7 7:R 8:R v71 9:R vd4 10:Wda v46 11:Wb9 12:R 13:X 14:W93 15:-
- Output
errors = 1, first_error = missing read_valid (2), first_error_edge = 13, entries_left = 1, read_pending = no
At the edge after a read, read_valid is 0: code 2 there.
Example 3
Wrong data- Input
edges (X reset, W accepted write + data, R accepted read, v read_valid + read_data): 1:- 2:- 3:- 4:- 5:- 6:- 7:Wf5 8:Wc8 9:R 10:X ve5 11:Wda 12:Wb9 13:- 14:- 15:-
- Output
errors = 1, first_error = wrong read_data (3), first_error_edge = 10, entries_left = 2, read_pending = no
read_valid comes on time, but with one bit flipped: code 3.
Constraints and contract
- An accepted read never arrives while expected is empty.
- Keep the class, field and method names.
- Check the response before you record this edge’s read.
Hints
Hint 1
Draw three edges: a write, then a read, then nothing. At which edge should read_valid be 1?
Hint 2
The read accepted at this edge is answered at the next one, so you need a place to keep it: pending and pending_data.
Hint 3
Order matters: compare with the old pending first, then overwrite pending with this edge’s read_acc.
What this judge verifies: Your scoreboard reads 25 monitor traces from a depth-3 FIFO with resets, clean and with missing, extra, late or wrong responses. Passing shows it flags exactly the faulty edges in them.
25 checks on Verilator · local server. Run the examples first, then check the full regression. The suite is local and inspectable. A passing result establishes the tested cases, not a proof for all possible inputs.
See all 6 steps and the final capstone