02Verification
Find the parameter a generator loop ignores
Problem
Intended behavior. Gains drives two 8-bit outputs from one Scala
method, gain(in, doublings, bias), which builds in * 2^doublings + bias
from a chain of adders. x4p3 is gain(in, 2, 3), that is 4 * in + 3, and
x2p1 is gain(in, 1, 1), that is 2 * in + 1. Both wrap modulo 256.
Current behavior. The starter compiles and runs. x2p1 is right for
every input, but x4p3 is wrong for the nonzero inputs in the public run.
Your task. Find out why one call of the same method builds the wrong
circuit, and fix gain itself. Keep the ports and both calls, with their
arguments, unchanged.
Read and predict
gain prints one ELABORATE line for each doubling adder it builds and one
more for the bias adder. Those lines count the adder expressions the
generator builds, before any later optimization.
Before running, write down how many doubling lines each call should print,
and both outputs for inputs 1 and 5. Then run the starter and compare, first
the ELABORATE lines and then the SIMULATE lines.
Diagnose
The SIMULATE lines tell you which output is wrong; the ELABORATE lines
tell you why. Count the doubling lines for each call and compare the count
with each argument of that call. A loop that builds the wrong number of
adders is reading the wrong Scala value, and a call whose arguments happen to
be equal hides the mistake.
Nothing done at simulation time can repair this. The loop has finished before
the first poke.
Completion check
x4p3equals4 * in + 3andx2p1equals2 * in + 1, both modulo 256, for every 8-bit input.- Each call prints as many doubling lines as its
doublingsargument. - A fixed loop count that suits
gain(in, 2, 3)breaksgain(in, 1, 1). The fix has to work for any arguments.
Hints
Hint 1
Put the number of doubling lines for gain(2, 3) next to its two arguments.
Which argument does the count match?
Hint 2
Look at the upper bound of the for range. A generator parameter that the
loop never reads can change freely without changing the circuit.
Concept
In a generator, Scala parameters are the only inputs that shape the hardware.
When editing a parameter changes nothing, or changes the wrong thing, trace
where each loop bound and each Scala if gets its value. Prints during
elaboration are the quickest way to see what the generator actually built.
Variation
Add a third output driven by gain(io.in, 0, 7). With the fixed gain,
predict its ELABORATE lines and its value for input 10. Then work out what
the starter's version would have printed and computed for the same call.