Building the Capstone Controller FSM

A concept-level guide to control_fsm, the capstone controller built on the Module 4 dual-block pattern.

Updated 2026-07-27

control_fsm is the exact dual-block pattern from Module 4, applied to four states instead of three:

  • Block 1 (clocked): the state register — state <= next_state, or state <= IDLE on reset — extended by one more field, captured_op, latched from op_sel the cycle IDLE accepts a start request.
  • Block 2 (combinational): one always @(*) block that computes both next_state and every control output, each with a safe default at the top.

The four states each do one job:

  • IDLE waits for start. The instant it accepts a request, the clocked block latches op_sel into captured_op. Every combinational output stays at its default.
  • FETCH spends one cycle preparing to compute. Outputs still default.
  • EXECUTE asserts alu_op = captured_op and advances unconditionally to WRITEBACK.
  • WRITEBACK asserts reg_write_en and pulses done for exactly one cycle, then returns to IDLE.

Why capture instead of reading op_sel live: op_sel is only guaranteed valid the cycle start is accepted. Reading it directly in EXECUTE and WRITEBACK would mean a caller changing op_sel partway through an operation — deliberately or by accident — could change which operation actually gets written back, even though the FSM already committed to computing one. Capturing it once, in the same clocked block that already handles state, removes that hazard entirely: EXECUTE and WRITEBACK always agree on which operation is running, and the caller only has to hold op_sel stable for the one cycle it takes to be accepted.

Because every output is a Moore-style function of the current state (and the captured operation) alone, the same four-state shape works for every operation the ALU supports.