34Implementation
Build a bounded rule expression
Problem
countToBound should construct a reusable Rules value for a supplied
four-bit register and bound. Its empty rules block is a valid value, so the
starter can compile, but addRules installs no behavior. The public trace
therefore leaves count at zero instead of ramping to four and holding there.
Add only the missing rule inside the existing expression. Preserve the
function parameters, Rules return type, addRules call, observation rules,
and supplied mkTop.
Read, predict, and implement minimally
Read the file in two time domains. During elaboration,
countToBound(count, 4) constructs a Rules value and addRules installs it.
During simulation, the installed rule evaluates its guard and may schedule a
register write each cycle.
Before editing, predict the public trace: advance can print successive cycle
values, but the empty collection cannot change count. Then identify the only
editable structural gap—the space between rules and endrules.
Add one named rule whose guard distinguishes “below the bound” from “at the
bound.” Its body should schedule one increment. Avoid adding a second register,
putting the boundary test inside an always-enabled body, or moving behavior into
mkTop; those changes defeat the reusable rule-expression contract.
After Run, inspect the full sequence rather than only its last line. Starting from zero with bound four, entry states 0, 1, 2, and 3 should schedule the next four states. At entry state 4, the installed rule must be disabled, so later observations remain exactly four.
Observable completion contract
- For a bound of four, the count advances one per firing from zero to four and then remains four across multiple later cycles.
- A smaller and a larger bound must both work through the same function; no literal bound belongs in the returned rule.
- A zero bound permits no increment, because the initial state is already at the boundary.
- The counter never overshoots its supplied bound.
Progressive hints
Hint 1 — locate construction versus execution
The function does not increment the register while elaborating. It must return a rule definition that can increment the register later.
Hint 2 — reason about the boundary
Evaluate candidate guards when count is one below bound and when it is
equal to bound. The rule should be enabled only in the first case.
Hint 3 — narrow the syntax
Place a rule declaration inside the existing rules block. Put the comparison
in its parenthesized guard and use one scheduled register assignment in its
body.
Transfer experiment
After the required version works, use a scratch copy to install the same
function twice for two registers with different bounds. Predict both ramps.
This demonstrates that one rule-building function can elaborate distinct rule
instances. Restore the supplied mkTop before submitting.