Skip to content
code0.HDL

03Implementation

Split work across two rules

Problem

mkRuleOrder collects four values into accumulator and then hands the finished total to result. Two rules divide that work: fill accumulates while collecting is true and clears the flag once four values are taken, and drain moves the finished total across and empties the accumulator.

Both rules currently carry the same condition, so they want the same cycles and the same register. With the compiler used by Run, G0010 reports that fill was treated as more urgent and G0021 reports that drain can never fire in the generated schedule.

Give drain at the TODO a condition that becomes true after fill stops and becomes false again after the completed result has been drained once.

Read the starter

Track the five registers in mkRuleOrder. fill accumulates four terms while collecting is true. drained records whether the one allowed transfer already happened. drain should copy the completed sum and clear the accumulator only after collection ends.

Predict before editing

Both rules currently use the same condition and both write accumulator. Predict the write conflict while collecting is true, then inspect what can happen after it becomes false.

Trace the broken starter before editing:

CycletotalemittedfillingMeaning
0001fill can add 1
1101next add 2
2301next add 3
3601next add 4
41000collection ended; starter drain is now disabled
5 and later1000the completed total remains stranded

Make the smallest change

  • Accumulate all four values in the fill rule, reaching a total of ten.
  • Move the finished total to emitted from the drain rule.
  • Keep the two rules from ever wanting the same cycle.
  • Keep the emitted result stable after the single drain cycle.

Change only the readiness condition on drain. Do not add priority attributes or state registers.

The readiness condition must establish two facts from the existing state: collection is no longer active, and the single drain opportunity has not been used. Derive the Boolean expression from those facts. Grading checks the resulting one-transaction behavior rather than one source spelling.

Run and explain

Run the repaired design and follow filling, total, and emitted. The corrected conditions divide execution into collection and drain phases. Explain why the rules no longer compete for accumulator and why drain sees the fully committed sum.

With the repair, cycle 4 is the handoff observation (total = 10, emitted = 0). drain then fires once. Cycle 5 observes total = 0 and emitted = 10; later cycles keep that emitted result stable.

Completion check

  • fill owns every collection cycle.
  • drain cannot fire while collection is active.
  • The emitted value contains the complete accumulated result.
  • The emitted value remains stable after the accumulator is empty.
  • The guards divide collection and drain into disjoint phases.

Progressive hints and concept

Hint 1

fill runs while collecting holds. drain needs the opposite phase and an unused one-shot token.

Hint 2

Combine the completed-collection state with the false state of drained.

Concept

The compiler builds a schedule from each rule's conditions and the state it touches. Two rules conflict when each reads what the other writes; then only one fires in that cycle. Two rules that merely write the same register can both fire, with the later write in schedule order winning and bsc warning about the other. Making the conditions mutually exclusive removes the conflict. The drained state also closes the transfer after one firing, so the result is not overwritten by a later empty accumulator.

Extension experiment

After the required solution works, initialize accumulator to eight instead of zero. Predict the trace 8, 9, 11, 14, 18 and an emitted total of 18, then verify that the one-shot drain still preserves that result on later cycles.

Review this concept
Ready
Main.bsv