17Implementation
Close a ready-valid valve in both directions
Problem
Intended behavior. Valve sits on a Decoupled link between a producer
(in) and a consumer (out). While open is high it is transparent: the
producer's offer reaches the consumer, and the consumer's ready reaches the
producer. While open is low, nothing passes. In every cycle the producer
and the consumer must agree: a value leaves the producer exactly when the
consumer receives it.
Current state. The forward half is written. out.bits follows the producer
directly, while out.valid is gated by open. The backward half is a
placeholder that holds in.ready low, so the producer never sees a transfer
and keeps offering the same value.
Your task. Replace the TODO assignment so in.ready reports the cycles
in which the offered value really passes through. Keep the ports and the
forward assignments unchanged.
Read and predict
The public run plays both ends. The producer offers 1, then 2, and so on,
moving to the next value only after a cycle with sent=1. The consumer's
ready and the open input follow fixed patterns. got shows the value the
consumer received in that cycle, or -.
Run the starter first. Predict how often the consumer receives 1, and why
that is worse than receiving nothing. Then, for a correct valve, predict the
sent column: it must equal 1 in exactly the cycles where got is not -,
and the consumer must receive 1, 2, 3, 4 once each.
Find the rule
A transfer on a ready-valid link happens when valid and ready are high in
the same cycle. On the consumer side, valid is already gated by open. Ask
what the producer must see so that its own fire is true in exactly the same
cycles as the consumer's fire.
Run and explain
Run the repaired valve. The sent column must be 1 on exactly the lines where
got shows a value, and got must read 1, 2, 3, 4 in order. Then look at
cycle 2, where open is low while the consumer is ready, and explain what your
in.ready reports there and why.
Completion check
- When
openis high,in.readyfollows the consumer'sready. - When
openis low, the producer never sees a transfer, even if the consumer is ready. - In every cycle,
in.fireandout.fireare equal: no value is lost and none is duplicated. - Passing
readystraight through is not enough; check a cycle whereopenis low and the consumer is ready.
Hints
Hint 1
The starter's duplicate 1s come from a consumer-side transfer the producer
never heard about. The opposite mistake loses values instead.
Hint 2
The backward signal needs the same gate as the forward one. Combine the
consumer's ready with open.
Concept
Decoupled carries signals in both directions, so any logic placed on the
link must treat both. Gating only valid makes the two ends disagree about
which cycles transferred data. The fire of each side has to describe the
same event.
Variation
Suppose open also had to wait for a value: the valve opens only while
in.bits is even. Predict which parts of the forward and backward logic
change, and which values from the public stream would reach the consumer.