power β€” Power and Thermal Modeling

Hierarchical power state management, dynamic voltage/frequency scaling, thermal simulation, and energy estimation for simulated components.

📚 What is this & why does it exist?

πŸ’‘ Think of it like a power grid…

Imagine a city's electrical grid. VoltageDomain is a substation providing power at a specific voltage. PowerDomain is a city block with its own breaker panel controlling which buildings (components) are powered. DVFSHandler is the grid operator who adjusts voltage and frequency based on demand. PowerModel is the meter on each building tracking consumption, and ThermalDomain monitors temperature to prevent overheating β€” like a thermostat for the entire neighborhood.

Architecture Overview

The power sub-module models hardware power management features found in modern SoCs. It provides a layered approach: VoltageDomain defines voltage levels, PowerDomain groups components into power islands, PowerState tracks per-component power states (ON/CLK_GATED/OFF), and PowerModel computes dynamic and static power consumption.

graph TB
    DVFSHandler["DVFSHandler\n(voltage/frequency controller)"]
    VoltageDomain["VoltageDomain\n(voltage level)"]
    ClockDomain["ClockDomain\n(frequency)"]
    PowerDomain["PowerDomain\n(power island)"]
    PowerState["PowerState\n(per-component)"]
    PowerModel["PowerModel\n(energy estimation)"]
    ThermalDomain["ThermalDomain\n(heat zone)"]
    ThermalModel["ThermalModel\n(thermal simulation)"]
    ThermalNode["ThermalNode\n(temperature point)"]

    DVFSHandler --> VoltageDomain
    DVFSHandler --> ClockDomain
    VoltageDomain --> ClockDomain
    PowerDomain --> PowerState
    PowerState --> PowerModel
    PowerModel --> ThermalDomain
    ThermalDomain --> ThermalNode
    ThermalModel --> ThermalNode
    

Power State Machine

Each ClockedObject has an associated PowerState that tracks its current power mode. The state machine follows ACPI-inspired power states, enabling detailed power-aware simulation.

stateDiagram-v2
    [*] --> ON
    ON --> CLK_GATED : Clock gating
    CLK_GATED --> ON : Resume
    ON --> SRAM_RETENTION : Deep idle
    SRAM_RETENTION --> ON : Wake
    CLK_GATED --> SRAM_RETENTION : Deeper sleep
    SRAM_RETENTION --> OFF : Full shutdown
    ON --> OFF : Power off
    OFF --> ON : Power on
    

PowerState Class

class PowerState : public SimObject
{
  public:
    enum State {
        ON,              // Fully operational
        CLK_GATED,       // Clock stopped, state retained
        SRAM_RETENTION,  // Minimal power, SRAM preserved
        OFF              // Powered off, state lost
    };

    PowerState(const Params &p);

    void set(State s);
    State get() const { return _currState; }

    // Time tracking for statistics
    Tick getTimeInState(State s) const;
    double getPercentInState(State s) const;

    // Power domain membership
    void setControlledDomain(PowerDomain *d);

  private:
    State _currState;
    std::vector<Tick> stateResidencyTicks;
    std::vector<statistics::Scalar *> ticksInState;
};

Voltage Domain

VoltageDomain represents a voltage rail shared by one or more clock domains. The DVFS handler adjusts the voltage when changing operating points. Each voltage domain maintains a list of supported voltage levels.

class VoltageDomain : public SimObject
{
  public:
    VoltageDomain(const Params &p);

    double voltage() const { return _voltages[perfLevel]; }
    void voltage(double v);

    // Performance level (maps to voltage/frequency pair)
    uint32_t perfLevel() const { return _perfLevel; }
    void perfLevel(uint32_t level);
    uint32_t numPerfLevels() const { return _voltages.size(); }

  private:
    std::vector<double> _voltages;  // Voltage per perf level (V)
    uint32_t _perfLevel;              // Current performance level
};

DVFS Handler

The DVFSHandler coordinates dynamic voltage and frequency scaling across domains. It provides an interface for software (e.g., the simulated OS governor) to request performance level changes, then orchestrates the voltage and clock transitions with appropriate latency.

class DVFSHandler : public SimObject
{
  public:
    DVFSHandler(const Params &p);

    // Check if DVFS is enabled
    bool isEnabled() const { return enableHandler; }

    // Get/set performance level for a domain
    bool perfLevel(DomainID domain_id, PerfLevel perf_level);
    PerfLevel perfLevel(DomainID domain_id) const;

    // Transition latency
    Tick transLatency() const { return _transLatency; }

    // Get available domains
    uint32_t numDomains() const;
    std::vector<DomainID> domainIds() const;

    // Frequency/voltage for a perf level
    Tick clkPeriodAtPerfLevel(DomainID id, PerfLevel level) const;
    double voltageAtPerfLevel(DomainID id, PerfLevel level) const;

  private:
    bool enableHandler;
    Tick _transLatency;
    std::unordered_map<DomainID, ClockDomain *> domains;
};

Power Model

The PowerModel estimates energy consumption based on component activity, voltage, and frequency. It separates power into dynamic (activity-dependent) and static (leakage) components.

PowerModel Interface

class PowerModel : public SimObject
{
  public:
    // Total power = dynamic + static
    double getDynamicPower() const;
    double getStaticPower() const;
    double getTotalPower() const {
        return getDynamicPower() + getStaticPower();
    }

    // Temperature-dependent leakage
    void setTemperature(double temp);

    // Associate with a ClockedObject
    void setClockedObject(ClockedObject *obj);

  private:
    std::vector<PowerModelState *> states;
    ClockedObject *clkObj;
    double dynamicPower;
    double staticPower;
};

PowerModelState

class PowerModelState : public SimObject
{
  public:
    virtual double getDynamicPower() const = 0;
    virtual double getStaticPower() const = 0;
    virtual void setTemperature(double temp) = 0;

    ClockedObject *clkObj;
    double temperature;  // Current temperature in Celsius
};

Thermal Modeling

The thermal subsystem models heat generation and dissipation. ThermalDomain represents a physical area that generates heat (from its PowerModel), while ThermalNode tracks temperature at a point, and ThermalModel solves the thermal network equations.

graph LR
    CPU["CPU Core\n(PowerModel)"]
    Cache["L2 Cache\n(PowerModel)"]
    TD1["ThermalDomain\n(CPU zone)"]
    TD2["ThermalDomain\n(Cache zone)"]
    TN1["ThermalNode\n(junction temp)"]
    TN2["ThermalNode\n(ambient)"]
    TM["ThermalModel\n(RC network solver)"]

    CPU --> TD1
    Cache --> TD2
    TD1 --> TN1
    TD2 --> TN1
    TN1 --> TM
    TN2 --> TM
    TM --> TN1
    

ThermalDomain Class

class ThermalDomain : public SimObject
{
  public:
    ThermalDomain(const Params &p);

    // Get total power dissipated in this domain
    double getPower() const;

    // Temperature feedback from thermal model
    void setTemperature(double temp);
    double getTemperature() const { return _temperature; }

    // Power models contributing to this domain
    void addPowerModel(PowerModel *pm);

  private:
    std::vector<PowerModel *> powerModels;
    double _temperature;
};

ThermalModel Class

class ThermalModel : public ClockedObject
{
  public:
    ThermalModel(const Params &p);

    // Solve thermal network using linear solver
    void doStep();

    // Node and domain management
    void addDomain(ThermalDomain *d);
    void addNode(ThermalNode *n);
    void addReference(ThermalNode *n);  // Ambient node

  private:
    std::vector<ThermalDomain *> domains;
    std::vector<ThermalNode *> nodes;
    ThermalNode *ambient;
    LinearSystem *solver;
};

Power Domain

PowerDomain groups multiple PowerState-enabled objects into a power island. When a domain transitions to a lower power state, all its members transition together. It enforces hierarchical constraints β€” a domain can only be as awake as its most-awake member.

class PowerDomain : public PowerState
{
  public:
    PowerDomain(const Params &p);

    // Add/remove members
    void addFollower(PowerState *ps);

    // Calculate effective domain state
    State calculateState() const;

    // Apply state to all members
    void pwrStateChangeCallback(State old_state, State new_state);

  private:
    std::vector<PowerState *> followers;
    // Domain is ON if ANY member is ON
    // Domain is OFF only if ALL members are OFF
};

πŸ” Narrated Walkthrough: DVFS Transition

  1. Governor Memory System | gem5 Wiki" class="xref">Request β€” The simulated OS power governor (or a user script) requests a performance level change via DVFSHandler::perfLevel(domainId, newLevel).
  2. Validation β€” The handler verifies the requested level is valid for the target domain and that DVFS is enabled.
  3. Voltage Transition β€” If frequency is decreasing, the voltage is lowered first via VoltageDomain::perfLevel(). The new voltage takes effect immediately.
  4. Frequency Transition β€” The ClockDomain frequency is updated. A transition latency event is scheduled to model the PLL lock time.
  5. Power Update β€” Once the transition completes, PowerModel recalculates dynamic power using the new VΒ² Γ— f formula. Static power is also updated based on the new voltage.
  6. Thermal Feedback β€” On the next thermal model step, the new power values feed into ThermalDomain, which updates the temperature. If temperature exceeds a threshold, the governor may throttle back.

Configuration Example

// Python configuration for DVFS-enabled system
voltage_domain = VoltageDomain(
    voltage=['1.0V', '0.9V', '0.8V']  # 3 perf levels
)

clock_domain = SrcClockDomain(
    clock=['1GHz', '800MHz', '600MHz'],
    voltage_domain=voltage_domain
)

dvfs_handler = DVFSHandler(
    domains=[clock_domain],
    enable=True,
    transition_latency='10us'
)

# Thermal setup
thermal_domain = ThermalDomain()
thermal_node = ThermalNode(temperature=25.0)  # 25Β°C ambient
thermal_model = ThermalModel(step_size='1ms')

Key Components Reference

ComponentHeaderPurpose
PowerStatepower_state.hhPer-component power state tracking (ON/CLK_GATED/SRAM_RETENTION/OFF)
PowerDomainpower_domain.hhHierarchical grouping of power states into islands
VoltageDomainvoltage_domain.hhVoltage rail with multiple performance levels
DVFSHandlerdvfs_handler.hhDVFS transition coordination and latency modeling
PowerModelpower_model.hhDynamic + static power estimation
PowerModelStatepower_model.hhAbstract per-state power calculation
ThermalDomainthermal_domain.hhHeat-generating zone with temperature tracking
ThermalModelthermal_model.hhThermal network solver (RC equivalent circuit)
ThermalNodethermal_node.hhTemperature point in thermal network

Glossary

TermDefinition
DVFSDynamic Voltage and Frequency Scaling β€” adjusting voltage and clock speed at runtime for power savings
Power IslandGroup of components sharing a single power switch, enabling collective power gating
Clock GatingStopping the clock to a component to eliminate dynamic power while retaining state
Leakage PowerStatic power consumed due to transistor leakage currents, even when not switching
Dynamic PowerPower consumed during switching activity, proportional to CΓ—VΒ²Γ—f
Thermal ThrottlingReducing performance to prevent exceeding safe temperature limits
Performance LevelA voltage/frequency operating point β€” higher levels = more performance, more power