27Implementation
Stretch a trigger into a three-cycle pulse
Problem
Intended behavior. PulseStretch turns a trigger into a pulse at least
three cycles long. count holds how many more cycles out must stay high,
and out is high whenever count is not 0. On each clock edge, a high trig
sets count to 3. Without trig, a nonzero count goes down by one and a
zero count stays 0. A one-cycle trigger therefore keeps out high for the
three cycles after its edge, and a new trigger during a pulse starts the three
cycles over. Reset clears count.
Current behavior. The starter declares count but never updates it, so
out never rises.
Your task. Replace the TODO line with the update for count. Keep the
ports, the declaration, the out line, and the public bench.
Read and predict
The public bench checks the design with expect calls, each carrying a
message that names the case. It catches the FailedExpectException and prints
its message on a FAILED line, so a failing run still ends normally and shows
the first expectation that did not hold. When every check holds, it prints one
PASS line per scenario.
Before running, walk through the bench with a table of trig, count, and
out after every poke and every step, and answer:
- Why must
outstill be 0 right aftertrigis poked, before any step? - In the retrigger scenario, how many cycles of the first pulse are left when the second trigger meets an edge?
Then run the starter and read the FAILED line.
Diagnose
The message has the shape you saw in the testbench chapter: the step number, the port name, the actual and expected values, and the case message. The step number counts clock steps from the start of the test body, so it points to one row of your table. After you write the update, run again. If the failure moves to a later step, the scenarios before it pass, and the new message names what is still wrong, for example the retrigger.
Completion check
- A one-cycle trigger gives exactly three high cycles, beginning at the edge that sees the trigger.
- A trigger while
outis high restarts the three cycles, whether one or two cycles were left. - A trigger held high for several cycles keeps
outhigh, and three high cycles follow its last edge. countnever wraps below 0, and the synchronous reset ends a pulse at the next rising edge.
Hints
Hint 1
State the rule as two cases with a priority: what happens on an edge with
trig, and what happens on every other edge. The second case has a condition
of its own.
Hint 2
Use when with .elsewhen. The decrement needs a guard that count is not
already 0; without it, the 2-bit register wraps to 3.
Concept
An expect with a message turns a mismatch into a precise report: which step,
which port, which values, and which scenario. A wrong value that only reaches
a println waits for someone to notice it. A wrong value caught by expect
stops the test at the cycle where it first appears.
Variation
Change the bench so that the second trigger arrives one step later, when only
one cycle of the first pulse is left. Predict how many cycles out stays high
in total, counted from the first trigger's edge, and check your answer with a
run.