01Implementation
Build a constant multiplier in a generator loop
Problem
Intended behavior. Scalers has one 8-bit input in and two 8-bit
outputs. x10 carries in * 10 and x7 carries in * 7, both modulo 256.
Both come from one Scala method, scale(in, factor), which builds the product
from adders only. Inside its loop, term refers to the 8-bit node for
in * 2^bit modulo 256: it starts as in and is doubled on every iteration. For each
bit of factor that is 1, the matching term must be added into total. For
10, binary 1010, that means the terms for bits 1 and 3, or in*2 + in*8.
Current behavior. The starter compiles and runs, but the loop never adds
anything to total, so both outputs are 0 for every input.
Your task. Replace the TODO line inside the loop so that scale builds
the right adders for any factor from 0 to 255. Keep the ports, the doubling
line, and the two calls unchanged.
Read and predict
Read scale as a program that runs while the circuit is being built, not as
hardware that loops at run time. factor and bit are Scala Ints whose
values are known during elaboration. in, term, and total refer to hardware
nodes whose signal values can change during simulation or circuit operation.
Before running, answer three questions:
- How many
ELABORATElines appear, and does any of them appear betweenSIMULATElines? - For input 3, what should
x10andx7be? - For input 30, what do they become once the result wraps to 8 bits?
Then run the starter and compare its SIMULATE lines with your predictions.
Decide what the loop must build
Whether a term is added depends only on factor, which is fixed before
simulation starts. That is exactly the kind of decision a Scala if can make:
it does not build a multiplexer, it chooses which hardware gets generated.
Testing one bit of a Scala Int is ordinary integer arithmetic. If the bit is
1, rebind total to a new adder node fed by the old total and the current
term. If the bit is 0, generate nothing.
Mind the order inside the loop. The decision for bit number bit has to use
term before the doubling line moves it on to the next power of two.
Completion check
x10equalsin * 10modulo 256 andx7equalsin * 7modulo 256 for every 8-bit input, not only the five values the public run pokes.- Both outputs still come from the same
scalemethod. A change that works for one factor and not the other does not complete the task. - The run still prints exactly one
ELABORATEline per call, before everySIMULATEline.
Hints
Hint 1
Ask which value decides whether an adder exists: a value known while the
circuit is built, or a value a wire carries during simulation. Only the first
kind can steer a Scala if.
Hint 2
Shift factor right by bit and test its lowest bit with Scala integer
operators. Inside the if, rebind the var total the same way the chapter's
Doubler rebinds x.
Concept
A generator decides the shape of the circuit with Scala values. The same
scale code builds two different adder networks: factor 10 adds two terms and
factor 7 adds three. After elaboration no trace of the if is left in the
hardware, only the adders it chose to build.
Variation
Add a third output x255 driven by scale(io.in, 255). Predict how many
terms the loop adds for that factor and what the output is for inputs 1 and 2.
Then compare your answers with in * 255 modulo 256.