Work through these steps before writing states. The cycle table becomes the coding plan.
Define the interface. Name the start, busy and done signals. State when start is honoured and how long the result stays valid.
List the phases. Load operands, repeat the step N times, then report. Each phase becomes one or more states.
Write the cycle table. Trace one example cycle by cycle: state, key registers and control signals.
Choose the counter. If N is variable, load N and count down to zero: a zero-detect is cheaper than comparing against a stored N. For a constant N either form is fine.
Define reset and idle. State what busy, done and the result show after reset and between operations.
The table fixes the handshake. The diagram shows the states around it.
Signal | Meaning | Rule |
|---|---|---|
| Begin an operation with the operands on the inputs | Honoured only in IDLE; ignored while busy |
| The block cannot accept a new operation | High through RUN and DONE; low only in IDLE. An operation is accepted on start && !busy |
| The result is valid this cycle | A one-cycle pulse; the result register stays stable afterwards |
operands | Inputs sampled on | Captured into registers, so they may change while busy |
Each slot is one clock cycle, sampled just after its rising edge. b stays 3 throughout. An input drawn in slot k is seen by the edge that opens slot k+1.
Slot 0: start is offered while busy is low, so the next edge accepts 5 and 3.
Slots 1 to 5: busy is high. start stays high and a changes to 9, and both are ignored: the result is still 5 × 3 = 15 (f).
Slot 5: done is high for one cycle with the product valid. busy is still high, so this cycle cannot accept.
Slots 6 and 7: busy is low and start is still high, so the edge opening slot 7 accepts the next operation (9 × 3) and the product register restarts from 0.
Ambiguous handshake semantics cause most integration bugs. Pin them down early.
start while busy?Starting while busy would overwrite the operand and loop registers in the middle of an operation and corrupt it. A busy block must either ignore the request (and expose busy so the caller waits) or queue it.