Fix a two-stage pipeline whose beats come out one edge early.
Hardware context: Clocked DUT pipeline observed across nonblocking updates. Observe a register before and after its nonblocking assignment at a clock edge.
This is a Fix problem: the code in the editor has one realistic defect. Find it and fix it.
delay2 is a two-stage register pipeline. A beat on in_valid and in_data just before edge k is captured into stage 1 at edge k and must be on out_valid and out_data right after edge k + 1. A monitor that samples just before each edge therefore sees it at edge k + 2. Reset empties both stages.
In simulation every beat comes out one edge early, as if the pipeline had a single stage. The scoreboard downstream expects two cycles and reports a mismatch for every beat.
For a single beat 5A presented before edge 1, out_valid must first be 1 after edge 2.
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
clk | 1 | stimulus, the same for every design |
rst | 1 | stimulus, the same for every design |
in_valid | 1 | stimulus, the same for every design |
in_data | 8 | stimulus, the same for every design |
out_valid | 1 | stimulus, the same for every design |
out_data | 8 | stimulus, the same for every design |
Full specification
module delay2 (
input logic clk, rst,
input logic in_valid,
input logic [7:0] in_data,
output logic out_valid,
output logic [7:0] out_data
);
// two register stages
endmodule
| After edge k | Correct pipeline |
|---|---|
| stage 1 | holds the inputs from just before edge k |
| out_valid, out_data | hold what stage 1 held before edge k, so the inputs from before edge k - 1 |
| rst = 1 before edge k | both valid bits are 0 after edge k; data may keep any value |
Each case resets the pipeline, then sets the inputs while the clock is low for 12 cycles and reads the outputs after every edge. It reports the first cycle with out_valid high, the number of beats out, the first and last beat, and the cycles with out_valid high.
Examples
Example 1
Through both stages- Input
in_valid 1 in cycle 1 with data 5A
- Output
first_out_cycle = 2, beats_out = 1, first_beat = 0x5a, last_beat = 0x5a, cycles_with_out_valid = {2}
Edge 1 captures the beat into stage 1, edge 2 moves it to the outputs: out_valid is 1 in cycle 2 only.
Example 2
A stream keeps its spacing- Input
beats 11, 22, 33 in cycles 1 to 3
- Output
first_out_cycle = 2, beats_out = 3, first_beat = 0x11, last_beat = 0x33, cycles_with_out_valid = {2, 3, 4}
They come out in cycles 2 to 4, in order.
Example 3
Reset drops the beats inside- Input
beats A1, B2 in cycles 2 and 3, reset in cycle 4, beat C3 in cycle 6
- Output
first_out_cycle = 3, beats_out = 2, first_beat = 0xa1, last_beat = 0xc3, cycles_with_out_valid = {3, 7}
A1 leaves in cycle 3; B2 is in stage 1 when reset comes and is lost. C3 leaves in cycle 7.
Constraints and contract
- Captured at edge k, on the outputs after edge k + 1, for every beat.
- Reset clears the valid bit of both stages.
- Keep the module name and ports.
Hints
Hint 1
Inside one always block, statements run in order. What value of s1_valid does the third statement read?
Hint 2
A flip-flop should capture the value its input had before the edge, not a value computed earlier in the same edge.
Hint 3
There are two ways to write an assignment in a clocked block. Only one of them delays the update until every block has read the old values.
What this judge verifies: The pipeline runs 24 traces of 12 cycles, some with a reset in the middle, and its outputs are read after every edge. Passing shows the two-edge delay and the reset on these traces.
24 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