cpu

cpu — CPU Timing Models

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

9
Sub-Modules
4
CPU Models
340+
Source Files
C++
Primary Language

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:

  1. 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.
  2. 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 StaticInst object.
  3. 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-decode TimeBuffer.
  4. 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.
  5. Cycle 5 — Rename: The Rename stage (o3/rename.hh) reads the RenameMap (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 the FreeList (o3/free_list.hh) and records the old mapping for later freeing. A ROB entry is allocated.
  6. Cycle 6 — Dispatch: The IEW stage (o3/iew.hh) receives the renamed instruction and dispatches it to the InstructionQueue (o3/inst_queue.hh). Since ADD is not a memory operation, it skips the LSQ.
  7. 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.
  8. Cycle 8 — Execute: The ALU computes x2 + x3. The result is written to the destination physical register. The Scoreboard marks the destination as ready, waking up any dependent instructions.
  9. Cycle 9 — Writeback: The IEW stage signals completion through the iew-to-commit TimeBuffer. The DynInst is marked as “completed” in the ROB.
  10. 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.
  11. 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.
  12. 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

ClassHeaderRole
BaseCPUcpu/base.hhAbstract base for all CPU models; provides ports, thread contexts, interrupts
o3::CPUcpu/o3/cpu.hhSuperscalar out-of-order CPU with 5-stage pipeline and SMT support
MinorCPUcpu/minor/cpu.hhIn-order pipelined CPU: Fetch1 → Fetch2 → Decode → Execute
BaseSimpleCPUcpu/simple/base.hhBase class for simple one-instruction-at-a-time CPU models
AtomicSimpleCPUcpu/simple/atomic.hhAtomic memory access model; fastest simulation, no timing
TimingSimpleCPUcpu/simple/timing.hhTiming-accurate memory model with cache port delays
BaseKvmCPUcpu/kvm/base.hhKVM hardware-accelerated CPU for fast-forward simulation
BPredUnitcpu/pred/bpred_unit.hhBranch predictor wrapper: manages BTB, conditional predictor, RAS
StaticInstcpu/static_inst.hhDecoded instruction with execute/disassemble methods
ExecContextcpu/exec_context.hhInstruction execution interface for reading/writing registers and memory
ThreadContextcpu/thread_context.hhPer-thread architectural state visible to the rest of the system
SimpleThreadcpu/simple_thread.hhLightweight thread state implementation used by Simple and Minor CPUs
CheckerCPUcpu/checker/cpu.hhFunctional checker that validates OOO CPU results
TraceCPUcpu/trace/trace_cpu.hhReplays elastic data/fetch dependency traces for memory system studies
FuncUnitcpu/func_unit.hhFunctional unit definition with operation classes and latencies

Sub-Module Overview

Pipeline — gem5 Wiki" href="o3/index.html" class="module-card">

o3

Out-of-Order Superscalar Pipeline

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.

48 files20K LOC5 pipeline stagesSMT

minor

In-Order Pipelined CPU

Four-stage in-order pipeline: Fetch1 → Fetch2 → Decode → Execute. Uses a configurable pipeline with buffered inter-stage communication and scoreboard-based hazard detection.

26 files8K LOC4 stagesScoreboard

simple

Atomic and Timing Simple CPUs

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.

18 files4K LOC2 variantsFastest sim

pred

Branch Prediction

Modular branch prediction framework: BTB, conditional predictors (2-bit local, tournament, bi-mode, gshare, TAGE, perceptron), indirect branch predictor, and Return Address Stack.

42 files12K LOC8+ algorithmsTAGE-SC-L

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.

testers

Memory system test generators: memtest for stress testing, rubytest for Ruby coherence protocol verification, traffic_gen for synthetic traffic patterns.

probes

CPU probe points for performance monitoring: instruction tracking, PC-based event counting, and SimPoint/LoopPoint profiling for sampling methodologies.

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

ParameterPython ClassDescriptionTypical Value
cpu_typeBaseCPUSelects the CPU model to instantiateO3CPU, MinorCPU, AtomicSimpleCPU
clockBaseCPUCPU clock frequency"2GHz"
numThreadsBaseCPUNumber of hardware threads (SMT)1–4
fetchWidthBaseO3CPUInstructions fetched per cycle4–8
decodeWidthBaseO3CPUInstructions decoded per cycle4–8
renameWidthBaseO3CPUInstructions renamed per cycle4–8
issueWidthBaseO3CPUInstructions issued per cycle4–8
commitWidthBaseO3CPUInstructions committed per cycle4–8
numROBEntriesBaseO3CPUReorder Buffer capacity128–256
numIQEntriesBaseO3CPUInstruction Queue size64–128
LQEntriesBaseO3CPULoad Queue entries32–64
SQEntriesBaseO3CPUStore Queue entries32–64
numPhysIntRegsBaseO3CPUPhysical integer register file size128–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()