The datapath is the part of the processor that holds and moves data: the PC, the instruction memory, the register file, the ALU, the data memory, and the multiplexers between them. The control unit decides, for each instruction, how the datapath is set up, by sending control signals.
One instruction, step by step
For lw r1, 8(r2) (load a word) in a simple single-cycle processor:
- The PC sends its address to the instruction memory, which returns the instruction.
- The register file reads r2.
- The ALU adds r2 + 8 to get the address.
- The data memory reads that address.
- The value is written into r1, and the PC moves on to PC + 4.
An add uses the same parts but skips the data memory; a sw (store word) writes memory instead of a register. The differences are exactly what the control signals choose.
Control signals
| Signal | Meaning when 1 |
|---|---|
| RegWrite | write a result into the register file |
| ALUSrc | the ALU's second input is the constant in the instruction (not a register) |
| MemRead / MemWrite | read / write the data memory |
| MemToReg | the value written to the register comes from memory (not the ALU) |
| Branch | a branch instruction: maybe change the PC |
# RegWrite ALUSrc MemRead MemWrite MemToReg Branch
CONTROL = {
"add": (1, 0, 0, 0, 0, 0),
"lw": (1, 1, 1, 0, 1, 0),
"sw": (0, 1, 0, 1, 0, 0),
"beq": (0, 0, 0, 0, 0, 1),
}
names = ["RegWrite", "ALUSrc", "MemRead", "MemWrite", "MemToReg", "Branch"]
for op, signals in CONTROL.items():
on = [n for n, s in zip(names, signals) if s]
print(op.ljust(4), "->", ", ".join(on))Hardwired and microprogrammed control
- Hardwired control is a combinational circuit (as in Digital Logic): opcode in, control signals out. Fast, and the usual choice for RISC processors.
- Microprogrammed control stores the signals for each step of each instruction in a small internal memory, the control store, and steps through it like a tiny program (microcode). Easier to design for complex instruction sets, and fixable after manufacture: x86 processors still use microcode for their most complex instructions, and receive microcode updates.
# Each instruction is a short list of micro-steps, read from a control store.
microcode = {
"LOAD": ["MAR <- PC", "IR <- memory[MAR]; PC <- PC + 1", "MAR <- IR.address", "ACC <- memory[MAR]"],
"ADD": ["MAR <- PC", "IR <- memory[MAR]; PC <- PC + 1", "MAR <- IR.address", "ACC <- ACC + memory[MAR]"],
}
for instruction, steps in microcode.items():
print(instruction)
for n, step in enumerate(steps, start=1):
print(" micro-step", n, ":", step)Common mistakes
- Thinking a store writes a register:
swhas RegWrite = 0. - Thinking the control unit computes results: it only sets switches; the ALU computes.
- Mixing up "microprogrammed" with "the operating system": microcode lives inside the processor, below everything else.
Quick check
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.