28Verification
Fix a countdown that never reports done
Problem
Intended behavior. Countdown waits a programmable number of cycles. On
an edge with load high, count takes the value of cycles. On every other
edge, a nonzero count goes down by one and a zero count stays 0. left
shows count, and done is high exactly when count is 0. After a load of
5, done rises five edges after the load edge. Reset clears count, so
done is high after reset.
Current behavior. The starter compiles, loads correctly, and starts
counting down, but after a load of 5 done never rises. The bench's wait loop
runs until chiseltest's idle-cycle timeout stops it.
Your task. Find why the count never reaches 0 and fix the design. Keep the ports and the public bench.
Read and predict
The bench sets a 20-cycle timeout, checks done after reset, loads 5, checks
left right after the load edge, and then steps until done reads 1. After
each step it prints WAIT n left=.... It catches the TimeoutException and
prints its message on a TIMEOUT line, so the run ends normally either way.
Before running, write the WAIT lines a correct countdown prints and the
number on its DONE line. Then run the starter and compare.
Diagnose
The timeout message only says that 20 cycles passed without an input-changing
poke. Peeking at outputs or poking the same input value does not restart that
count. It does not say why the countdown stalled. The WAIT lines do: find the first line where left stops
changing, and note the value it is stuck at. Then evaluate the condition that
guards the decrement at that value.
Also decide which side is wrong, the bench or the design. The contract says
done follows count reaching 0, so a longer timeout would only make the
same hang take longer.
Completion check
- After a load of
n,donerises exactlynedges after the load edge, for small values, for 1, and for the maximum 255. - A load of 0 keeps
donehigh, andleftnever wraps below 0. loadtakes priority over counting: loading again while counting restarts from the new value, and a heldloadkeeps reloading.- Raising
doneone value early is not a fix.leftitself has to reach 0.
Hints
Hint 1
At which value of left do the WAIT lines stop changing? Evaluate the
decrement condition with that value.
Hint 2
The decrement has to continue as long as count is not yet 0. Compare the
condition in .elsewhen with that rule.
Concept
A timeout bounds a wait but never explains it. Pair every wait loop with a trace or a check of the value it waits on, so that a hang points to the cycle where the design stopped making progress.
Variation
In the fixed design, lower the timeout to 4 and predict whether the run still passes. Then explain how the right timeout depends on the longest count the bench loads.