Skip to content
code0.HDL

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, dout after each rising edge equals the din sampled at the previous rising edge.
  • dout changes only at rising edges.
  • A reset in the middle of a run clears both stages, so the value that was in stage1 never reaches dout, 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.

Review this concept
Ready
Main.v