cpu
The cpu/ module implements gem5's suite of processor timing models, ranging from Atomic and Timing Simple CPUs — gem5 Wiki" href="simple/index.html">simple functional CPUs (AtomicSimpleCPU) to a detailed superscalar out-of-order pipeline (O3CPU). All models inherit from BaseCPU, which provides a unified interface for interrupt handling, thread contexts, memory port connections, and statistics collection.
⚙ O3 Superscalar 🔨 Minor In-Order 🚀 KVM Accelerated 🎯 Branch Prediction
CPU Class Hierarchy
All CPU models in gem5 derive from BaseCPU (defined in cpu/base.hh), which is itself a ClockedObject. This hierarchy allows the simulation framework to treat all CPU models uniformly for configuration, checkpointing, and statistics, while each model implements its own pipeline timing.
flowchart LR
subgraph BaseClasses["Base Framework"]
CO["ClockedObject"]
BCPU["BaseCPU\ncpu/base.hh"]
end
subgraph OOO["Out-of-Order"]
O3["o3::CPU\no3/cpu.hh"]
end
subgraph InOrder["In-Order"]
MINOR["MinorCPU\nminor/cpu.hh"]
end
subgraph Simple["Simple"]
BSC["BaseSimpleCPU\nsimple/base.hh"]
ATOMIC["AtomicSimpleCPU\nsimple/atomic.hh"]
TIMING["TimingSimpleCPU\nsimple/timing.hh"]
NONCACHE["NonCachingSimpleCPU\nsimple/noncaching.hh"]
end
subgraph KVM["Hardware Accel"]
BKVM["BaseKvmCPU\nkvm/base.hh"]
end
subgraph BranchPred["Branch Prediction"]
BPU["BPredUnit\npred/bpred_unit.hh"]
BTB["BTB\npred/btb.hh"]
RAS["RAS\npred/ras.hh"]
end
CO --> BCPU
BCPU --> O3
BCPU --> MINOR
BCPU --> BSC
BSC --> ATOMIC
BSC --> TIMING
BSC --> NONCACHE
BCPU --> BKVM
O3 -.->|"uses"| BPU
MINOR -.->|"uses"| BPU
BPU --> BTB
BPU --> RAS
O3 Pipeline Data Flow
The O3CPU implements a classic superscalar out-of-order pipeline with five major stages connected via TimeBuffer structs. Instructions flow front-to-back through the pipeline, while squash signals propagate back-to-front from Commit.
sequenceDiagram
participant BP as BPredUnit
participant FE as Fetch
participant DE as Decode
participant RN as Rename
participant IEW as IEW
participant ROB as ROB
participant CM as Commit
FE->>BP: predict(PC)
BP-->>FE: target + taken/not-taken
FE->>DE: fetchQueue (DynInst bundle)
DE->>DE: check branch targets, expand macros
DE->>RN: decodeQueue (decoded insts)
RN->>RN: map arch regs → phys regs (RenameMap)
RN->>IEW: renameQueue (renamed insts)
RN->>ROB: allocate ROB entry
IEW->>IEW: dispatch to IQ / LSQ
IEW->>IEW: issue ready insts to FUs
IEW->>IEW: execute + writeback
IEW->>CM: iewQueue (completed insts)
CM->>ROB: retire head instructions in order
CM->>RN: free old phys regs (FreeList)
Note over CM,FE: On misprediction: squash signal propagates back
CM-->>FE: squash(seqNum, correctPC)
Narrated Walkthrough: ADD Instruction Through O3
Follow a single ADD x1, x2, x3 instruction from fetch to retirement through the O3 pipeline:
- Cycle 1 — Fetch request: The Fetch stage (
o3/fetch.hh) sends the current PC to the ICache port. The branch predictor (pred/bpred_unit.hh) is consulted; since ADD is not a branch, prediction is “not taken” and next PC = PC+4. - Cycle 2 — ICache response: The Cache Hierarchy | gem5 Wiki" href="../mem_doc/cache/index.html">cache line arrives. The instruction decoder extracts the ADD machine instruction from the cache line and creates a
StaticInstobject. - Cycle 3 — DynInst creation: Fetch wraps the StaticInst in a
DynInst(o3/dyn_inst.hh) which carries dynamic state: sequence number, PC, thread ID, and physical register mappings. The DynInst is placed in the fetch-to-decodeTimeBuffer. - Cycle 4 — Decode: The Decode stage (
o3/decode.hh) validates the instruction, checks for PC-relative branches, and passes the DynInst to the decode-to-rename buffer. - Cycle 5 — Rename: The Rename stage (
o3/rename.hh) reads theRenameMap(o3/rename_map.hh) to translate architectural registers (x1, x2, x3) to physical registers. It allocates a new physical register for the destination (x1) from theFreeList(o3/free_list.hh) and records the old mapping for later freeing. A ROB entry is allocated. - Cycle 6 — Dispatch: The IEW stage (
o3/iew.hh) receives the renamed instruction and dispatches it to theInstructionQueue(o3/inst_queue.hh). Since ADD is not a memory operation, it skips the LSQ. - Cycle 7 — Issue: The IQ checks operand readiness via the
Scoreboard(o3/scoreboard.hh). Once x2 and x3’s physical registers are marked ready, the ADD is issued to an integer ALU functional unit. - Cycle 8 — Execute: The ALU computes x2 + x3. The result is written to the destination physical register. The
Scoreboardmarks the destination as ready, waking up any dependent instructions. - Cycle 9 — Writeback: The IEW stage signals completion through the iew-to-commit
TimeBuffer. The DynInst is marked as “completed” in the ROB. - Cycle 10 — Commit check: The Commit stage (
o3/commit.hh) examines the head of the ROB (o3/rob.hh). If the ADD is at the head and is marked completed, it is ready to retire. - Cycle 11 — Retire: Commit retires the ADD: the old physical register mapping is freed back to the FreeList, the ROB entry is deallocated, and the architectural commit map is updated.
- Cycle 12 — Stats update: The committed instruction counter increments. If this was the last instruction, the CPU may signal completion to the simulation framework.
Key Components
| Class | Header | Role |
|---|---|---|
BaseCPU | cpu/base.hh | Abstract base for all CPU models; provides ports, thread contexts, interrupts |
o3::CPU | cpu/o3/cpu.hh | Superscalar out-of-order CPU with 5-stage pipeline and SMT support |
MinorCPU | cpu/minor/cpu.hh | In-order pipelined CPU: Fetch1 → Fetch2 → Decode → Execute |
BaseSimpleCPU | cpu/simple/base.hh | Base class for simple one-instruction-at-a-time CPU models |
AtomicSimpleCPU | cpu/simple/atomic.hh | Atomic memory access model; fastest simulation, no timing |
TimingSimpleCPU | cpu/simple/timing.hh | Timing-accurate memory model with cache port delays |
BaseKvmCPU | cpu/kvm/base.hh | KVM hardware-accelerated CPU for fast-forward simulation |
BPredUnit | cpu/pred/bpred_unit.hh | Branch predictor wrapper: manages BTB, conditional predictor, RAS |
StaticInst | cpu/static_inst.hh | Decoded instruction with execute/disassemble methods |
ExecContext | cpu/exec_context.hh | Instruction execution interface for reading/writing registers and memory |
ThreadContext | cpu/thread_context.hh | Per-thread architectural state visible to the rest of the system |
SimpleThread | cpu/simple_thread.hh | Lightweight thread state implementation used by Simple and Minor CPUs |
CheckerCPU | cpu/checker/cpu.hh | Functional checker that validates OOO CPU results |
TraceCPU | cpu/trace/trace_cpu.hh | Replays elastic data/fetch dependency traces for memory system studies |
FuncUnit | cpu/func_unit.hh | Functional unit definition with operation classes and latencies |
Sub-Module Overview
o3
Full superscalar OOO CPU: Fetch → Decode → Rename → IEW → Commit with ROB, IQ, LSQ, register renaming, and SMT support. The most detailed and widely-used CPU model in gem5.
minor
Four-stage in-order pipeline: Fetch1 → Fetch2 → Decode → Execute. Uses a configurable pipeline with buffered inter-stage communication and scoreboard-based hazard detection.
simple
One-instruction-at-a-time models. AtomicSimpleCPU uses instant memory access for fast functional simulation. TimingSimpleCPU models cache port timing for basic memory system studies.
pred
Modular branch prediction framework: BTB, conditional predictors (2-bit local, tournament, bi-mode, gshare, TAGE, perceptron), indirect branch predictor, and Return Address Stack.
Other Sub-Modules
kvm
KVM-based hardware-accelerated CPU. Delegates instruction execution to the host CPU via Linux KVM for near-native speed during fast-forward simulation phases.
checker
Functional checker CPU that runs alongside OOO models, independently executing each instruction to validate correctness of speculative and reordered execution.
trace
Trace replay CPU that reads pre-recorded elastic dependency traces, generating memory access patterns for memory system research without simulating a full pipeline.
Directory Map
cpu/ source tree
cpu/
├── base.hh / base.cc ← BaseCPU: abstract base for all CPU models
├── static_inst.hh / .cc ← StaticInst: decoded instruction representation
├── exec_context.hh ← ExecContext: register/memory access interface
├── thread_context.hh / .cc ← ThreadContext: per-thread architectural state
├── simple_thread.hh / .cc ← SimpleThread: lightweight thread state
├── func_unit.hh / .cc ← FuncUnit: operation latency definitions
├── regfile.hh ← Physical register file
├── timebuf.hh ← TimeBuffer: inter-stage pipeline communication
├── o3/ ← Out-of-order superscalar CPU model
│ ├── cpu.hh / .cc ← o3::CPU main class
│ ├── fetch.hh / decode.hh ← Pipeline front-end stages
│ ├── rename.hh / iew.hh ← Rename and Issue/Execute/Writeback
│ ├── commit.hh / rob.hh ← Commit stage and Reorder Buffer
│ ├── inst_queue.hh / lsq.hh ← Instruction Queue and Load/Store Queue
│ └── rename_map.hh / free_list.hh ← Register renaming infrastructure
├── minor/ ← In-order pipelined CPU model
│ ├── cpu.hh / pipeline.hh ← MinorCPU and Pipeline container
│ ├── fetch1.hh / fetch2.hh ← Two-stage fetch unit
│ ├── decode.hh / execute.hh ← Decode and Execute stages
│ └── lsq.hh / scoreboard.hh ← Load/Store Queue and hazard detection
├── simple/ ← Simple CPU models
│ ├── base.hh / atomic.hh ← BaseSimpleCPU / AtomicSimpleCPU
│ ├── timing.hh / noncaching.hh ← TimingSimpleCPU / NonCachingSimpleCPU
│ └── exec_context.hh ← SimpleExecContext implementation
├── pred/ ← Branch prediction framework
│ ├── bpred_unit.hh / btb.hh ← BPredUnit wrapper and Branch Target Buffer
│ ├── tournament.hh / bi_mode.hh ← Classic conditional predictors
│ ├── tage.hh / tage_base.hh ← TAGE family predictors
│ └── ras.hh / indirect.hh ← Return Address Stack, indirect predictor
├── kvm/ ← KVM hardware-accelerated CPU
├── checker/ ← Functional correctness checker
├── trace/ ← Trace replay CPU
├── testers/ ← Memory system test generators
└── probes/ ← CPU instrumentation probes
Configuration Parameters
| Parameter | Python Class | Description | Typical Value |
|---|---|---|---|
cpu_type | BaseCPU | Selects the CPU model to instantiate | O3CPU, MinorCPU, AtomicSimpleCPU |
clock | BaseCPU | CPU clock frequency | "2GHz" |
numThreads | BaseCPU | Number of hardware threads (SMT) | 1–4 |
fetchWidth | BaseO3CPU | Instructions fetched per cycle | 4–8 |
decodeWidth | BaseO3CPU | Instructions decoded per cycle | 4–8 |
renameWidth | BaseO3CPU | Instructions renamed per cycle | 4–8 |
issueWidth | BaseO3CPU | Instructions issued per cycle | 4–8 |
commitWidth | BaseO3CPU | Instructions committed per cycle | 4–8 |
numROBEntries | BaseO3CPU | Reorder Buffer capacity | 128–256 |
numIQEntries | BaseO3CPU | Instruction Queue size | 64–128 |
LQEntries | BaseO3CPU | Load Queue entries | 32–64 |
SQEntries | BaseO3CPU | Store Queue entries | 32–64 |
numPhysIntRegs | BaseO3CPU | Physical integer register file size | 128–256 |
Example: Configuring an O3 CPU in Python
// gem5 Python configuration (m5 style)
import m5
from m5.objects import *
system = System()
system.cpu = O3CPU()
system.cpu.fetchWidth = 4
system.cpu.decodeWidth = 4
system.cpu.numROBEntries = 192
system.cpu.numIQEntries = 64
system.cpu.branchPred = TournamentBP()