16Verification
Keep a tag with its request
Problem
Intended behavior. Retime is a one-cycle pipeline register for a
TaggedLink. TaggedLink extends Link (data, valid) with a 4-bit tag
that names the unit that sent the request. Every field of out must equal the
corresponding field of in from the previous cycle, so a request and its tag
always arrive together.
Current behavior. The starter compiles and delays data and valid
correctly, but each request comes out with the tag of the request behind it.
A response routed by that tag would go to the wrong unit.
Your task. Find why the tag escapes the pipeline register, and make the whole link travel through it. Keep the bundle classes and the ports unchanged.
Read and predict
The testbench presents one request per cycle, (data, valid, tag) =
(10,1,1), (20,1,2), (30,0,3), (40,1,4), then an empty one. Each line
shows the request presented in that cycle on the left and out on the right.
Cycle 0 is not printed because the register has no reset value.
For a correct stage, predict the right side of every line from the previous
cycle's input. The first printed line, cycle 1, must contain cycle 0's
(10,1,1), even though cycle 0 has no printed line. Then run the starter and
compare the tag column with the data column on each line.
Diagnose
Read the declaration of stage and the connection into it. Ask two
questions. Which fields does a Link have? What does := do with a field on
its right side that the left side does not have? The patch that drives
out.tag is a symptom of the answer, not the cause.
Run and explain
Run the repaired stage. On every line, the right side must now equal the
previous cycle's input, and each tag must arrive with the data it was sent
with. Explain why changing the register's type, rather than the line that
drives out.tag, is what made the tag travel with its request.
Completion check
out.data,out.valid, andout.tagall equal the values ofinone cycle earlier, for every combination of fields.- A tag change without a data change also arrives one cycle later.
- Registering the tag separately next to an untagged stage is not the intent; the stage register should carry the full interface.
Hints
Hint 1
The connection stage := io.in compiles even though the two sides have
different interface types. The interfaces chapter describes which fields :=
copies and which it silently drops.
Hint 2
Declare the pipeline register with the same interface type as the ports. Then
connect out from the register as a whole, so no field is taken from in
directly.
Concept
An interface type is the contract for which signals travel together. Storing
or connecting a link through its parent class drops the fields the subclass
added. := does this without an error, so the loss shows up only as a timing
or routing fault much later.
Variation
Suppose the connection into the stage were written with :<>= instead of
:=, keeping the Link register. Predict in which phase the mismatch would
be reported, and why that would have prevented this defect.