Generate the directed test that pushes a FIFO one write past full and one read past empty.
Hardware context: Traffic generation and pin driving for FIFO verification. Drive a deterministic fill/drain sequence and verify normal termination.
The first directed test in the FIFO plan proves the two boundaries: the FIFO refuses a write when it is full and refuses a read when it is empty. A generator that stops at exactly depth writes never asks the FIFO to refuse anything, and the test passes against a FIFO that overflows.
Write fill_and_drain(depth, ops). Append one fifo_op per clock edge: first depth + 1 writes, carrying data 1, 2, 3 and so on, then depth + 1 reads. Never set both enables in one operation. ops arrives empty.
Your operations are replayed through the FIFO rules: the last write must be refused at full and the last read refused at empty.
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
depth | 8 | input of each check |
Full specification
typedef struct packed {
bit write_en;
bit read_en;
bit [7:0] data;
} fifo_op;
function automatic void fill_and_drain(input int depth, ref fifo_op ops[$]);
The replay counts operations, accepted and refused writes and reads, operations with both enables, whether write k (counting from 1) carries data k, whether every write comes before the first read, and the occupancy at the end.
Examples
Example 1
Depth 1- Input
depth = 1
- Output
operations = 4, writes_accepted = 1, writes_refused = 1, reads_accepted = 1, reads_refused = 1, both_enables = 0, write_data_in_order = yes, writes_before_reads = yes, final_occupancy = 0
Two writes (data 1, 2) and two reads: one of each is refused.
Example 2
Depth 3- Input
depth = 3
- Output
operations = 8, writes_accepted = 3, writes_refused = 1, reads_accepted = 3, reads_refused = 1, both_enables = 0, write_data_in_order = yes, writes_before_reads = yes, final_occupancy = 0
Four writes and four reads; write 4 meets a full FIFO and read 4 an empty one.
Example 3
Depth 16- Input
depth = 16
- Output
operations = 34, writes_accepted = 16, writes_refused = 1, reads_accepted = 16, reads_refused = 1, both_enables = 0, write_data_in_order = yes, writes_before_reads = yes, final_occupancy = 0
34 operations; the FIFO ends empty.
Constraints and contract
- depth is 1 to 16.
- Every operation has exactly one enable set.
- Keep the function name and arguments.
Hints
Hint 1
How many writes does it take to make the FIFO refuse one? Count from empty.
Hint 2
Two loops are enough: one for the writes, then one for the reads.
Hint 3
Build each operation as a struct value and push_back it; the data of write i (from 0) is i + 1.
What this judge verifies: Your operations are replayed through the FIFO rules at depths 1 to 16, counting accepted and refused operations and checking the write data. Passing shows the test crosses both boundaries once.
16 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 5 steps and the final capstone