Skip to content

Control Unit Design

After the datapath is built, the next step is designing the control unit. In a single-cycle CPU, the control unit is combinational logic that reads the current instruction fields and produces control signals within the same cycle.

Reference datapath

Figure 5.5: Reference datapath diagram.

Key control signals (for our minimal ISA subset):

  • RegWrite: register file write enable
  • ImmSrc: immediate type selection (I / S / B)
  • ALUSrc: ALU operand B source (0 = reg, 1 = imm)
  • MemWrite: data memory write enable
  • ResultSrc: write-back source select (0 = ALU, 1 = RAM)
  • ALUControl: ALU operation select
  • PCSrc: PC update select (0 = PC+4, 1 = branch target)

Instruction fields used:

  • opcode = Instr[6:0]
  • funct3 = Instr[14:12]
  • funct7[5] = Instr[30] (critical bit for ADD vs SUB)

A common implementation splits control into two blocks:

  1. Main decoder: based on opcode, outputs structural control signals and an intermediate ALUOp.
  2. ALU decoder: based on ALUOp plus funct3 and key bits, outputs ALUControl.

Controller block diagram

Figure 5.6: Control unit structure (main decoder + ALU decoder).

For BEQ, whether the branch is taken depends on the comparison result. Typically:

  • PCSrc = Branch AND Zero
  • Understand where control signals come from and what they do.
  • Learn a practical decoding design method.
  • Implement a ControlUnit subcircuit in Logisim Evolution.
  • Simulator: Logisim Evolution

Two-level decoding:

  • main decoder: opcodeRegWrite, ImmSrc, ALUSrc, MemWrite, ResultSrc, Branch, ALUOp
  • ALU decoder: ALUOp + funct3 + key bits → ALUControl

And for BEQ:

  • PCSrc = Branch · Zero

Encoding conventions:

  • ImmSrc: 00 = I, 01 = S, 10 = B
  • ALUOp: 00 = ADD, 01 = SUB (for BEQ), 10 = use funct fields

InstropcodeRegWriteImmSrcALUSrcMemWriteResultSrcBranchALUOp
R-type0110011
ADDI0010011
LW0000011
SW0100011
BEQ1100011

Table 5.4: Main decoder truth table (fill in during the lab; “don’t care” can be marked as --).

Inputs: ALUOp, funct3, {op5, funct7_5}. Output: ALUControl (must match your ALU encoding).

InstrALUOpfunct3{op5, funct7_5}ALUControl
LW / SW00
BEQ01
ADD / ADDI10
SUB10

Table 5.5: ALU decoder truth table (fill in during the lab).

Inputs:

  • Instr (32-bit)
  • Zero

Outputs:

  • RegWrite, ImmSrc, ALUSrc, MemWrite, ResultSrc, PCSrc, ALUControl

Use tunnels to keep wiring clean.

Inject instruction encodings and check outputs:

InstrAssemblyHex encoding
ADDadd x3, x1, x20x002081B3
SUBsub x3, x1, x20x402081B3
ADDIaddi x3, x1, 40x00408193
LWlw x3, 0(x1)0x0000A183
SWsw x3, 0(x1)0x0030A023
BEQbeq x1, x2, +80x00208463

Table 5.6: Test instruction encodings for control-unit verification.

  • Screenshot of the complete control unit.
  • Verification records for the test instructions (expected vs observed control signals).
  1. Why split decoding into “main decoder + ALU decoder”?
  2. Why can’t PCSrc for BEQ be decided purely by opcode?
  3. What should you do when encountering an unsupported instruction?