10Verification
Find the missing stage in a delay line
Problem
Intended behavior. delay2 is a two-stage delay line. At each rising edge,
the first stage stage1 captures din, and the output stage dout captures
what stage1 held before that edge. A value sampled into stage1 at one
rising edge therefore appears on dout after the next rising edge, one line later
in the public trace than it reached stage1. Reset is synchronous and active-high and
clears both stages.
Current behavior. The starter compiles and runs, and its reset works. In
the public output, though, stage1 and dout are identical on every line, and
dout repeats din on the same line instead of one line later. The design
behaves like a single register.
Your task. Find why the second stage collapses into the first and correct
the always block. Keep the ports, the internal stage1, the synchronous
reset, and the public testbench unchanged.
Diagnose with the waveform
The testbench records tb and everything below it, so the waveform includes
tb.dut.stage1 next to din and dout. Each line of the text output is
printed on a falling edge, after the rising edge has done its work.
Before editing, predict the dout column for the ten cycles of a correct delay
line: line n should show the din of line n − 1. Then open the waveform
and compare the rising edges at which stage1 and dout change. In a working
two-stage pipeline they change on different edges for the same input value.
Here, find the edge where both move at once, and ask which statement made
dout read the value stage1 had just received.
Fix, run, and explain
Make the smallest change that lets both stages read their inputs from before
the edge, run again, and check two things: the dout column now trails din
by one line, and in the waveform dout changes one rising edge after stage1
for every value. Then explain why the starter's text and the synthesized
hardware would agree with each other but not with the specification.
Completion check
- Without reset,
doutafter each rising edge equals thedinsampled at the previous rising edge. doutchanges only at rising edges.- A reset in the middle of a run clears both stages, so the value that was in
stage1never reachesdout, and the first output after reset is 0.
Progressive hints
Hint 1
Two registers that update at the same edge should each see the other's value from before the edge. In the waveform, the starter's stages do not.
Hint 2
Look at how the statements inside the clocked block assign. One kind of assignment updates its target immediately, so the next line already reads the new value.
Hint 3
The Testbench chapter's swap example shows the two assignment kinds side by side. Use the one meant for clocked logic in every branch of this block.
Transfer experiment
Keep the starter's assignment kind but reverse the two statements in the
else branch so that dout is assigned first. Predict the trace before
running. Then explain why that version happens to pass while the original does
not, and why depending on statement order is fragile once a third stage or a
second always block is added.