Compare two response streams position by position and report the first place they disagree.
Hardware context: Ordered completion streams from a pipelined hardware block. Find the earliest difference between expected and observed FIFO-ordered completions.
A scoreboard sorted its responses before comparing them, so a DUT that returned them in the wrong order still passed. Order is part of what a FIFO promises. The check has to compare position 0 with position 0, position 1 with position 1, and so on.
Write first_fifo_mismatch(expected, observed, expected_count, observed_count). Each array holds up to 16 completion words; only the first count of each are real. Scan the positions both streams have. The first position where the words differ is a MISMATCH. If every shared position matches but one stream is longer, report the first word the other stream is MISSING, or the first EXTRA word.
For expected = [0123, 0245] and observed = [0245, 0123], the same words are present, but position 0 already differs: a MISMATCH at index 0.
A count outside 0 to 16 is BAD_COUNT; check both counts before reading any word.
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
expected_words | 256 | input of each check |
observed_words | 256 | input of each check |
expected_count | 32 | input of each check |
observed_count | 32 | input of each check |
Full specification
function automatic logic [47:0] first_fifo_mismatch(
input logic [15:0] expected[16], observed[16], input int expected_count, observed_count);
// returns {status[7:0], index[7:0], expected_word[15:0], observed_word[15:0]}
| status | When | index, expected_word, observed_word |
|---|---|---|
| 0 MATCH | equal counts and every position matches | 255, 0, 0 |
| 1 MISMATCH | first shared position i where the words differ | i, expected[i], observed[i] |
| 2 MISSING | shared positions match, expected is longer | observed_count, expected[observed_count], 0 |
| 3 EXTRA | shared positions match, observed is longer | expected_count, 0, observed[expected_count] |
| 4 BAD_COUNT | either count is outside 0 to 16 | 255, 0, 0 |
A mismatch in the shared positions wins over a length difference. Words after each count are leftover storage and must not affect the result.
Examples
Example 1
Same words in the same order- Input
expected = [0123, 0245], observed = [0123, 0245]
- Output
status = MATCH (0), index = none (255), expected_word = 0x0, observed_word = 0x0
Both positions match and the counts are equal.
Example 2
Reordering is a mismatch- Input
expected = [0123, 0245], observed = [0245, 0123]
- Output
status = MISMATCH (1), index = 0, expected_word = 0x123, observed_word = 0x245
Position 0 holds 0245 where 0123 was expected.
Example 3
The last response never came- Input
expected = [0123, 0245], observed = [0123]
- Output
status = MISSING (2), index = 1, expected_word = 0x245, observed_word = 0x0
Position 0 matches; the expected stream has one more word, 0245, so it is MISSING at index 1.
Constraints and contract
- Words are known 16-bit values; repeated and zero words are legal.
- Compare positions, never sets: do not sort or search ahead.
- Keep the signature.
Hints
Hint 1
How many positions do both streams actually have? Only those can be compared word with word.
Hint 2
Return at the first differing position. Only when every shared position matches does the length difference decide the answer.
Hint 3
Validate both counts first; reading expected[i] for an i past a bad count would compare leftover storage.
What this judge verifies: Your function is run on directed and seeded streams of 0 to 16 words with reordering, repeats, missing and extra words, leftover storage after each count and invalid counts. Passing shows the first difference is found on these inputs.
331 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