diff options
author | Stephan Diestelhorst <stephan.diestelhorst@arm.com> | 2014-06-30 13:56:06 -0400 |
---|---|---|
committer | Stephan Diestelhorst <stephan.diestelhorst@arm.com> | 2014-06-30 13:56:06 -0400 |
commit | 65cea4708e2f2f2cb361e12b6385d4bc29618223 (patch) | |
tree | 9f190702d43e89e2ddb44b6af363330f301ec8fb /src/sim/clock_domain.cc | |
parent | 641e6028304187468b94753752555e9d082a77ac (diff) | |
download | gem5-65cea4708e2f2f2cb361e12b6385d4bc29618223.tar.xz |
power: Add basic DVFS support for gem5
Adds DVFS capabilities to gem5, by allowing users to specify lists for
frequencies and voltages in SrcClockDomains and VoltageDomains respectively.
A separate component, DVFSHandler, provides a small interface to change
operating points of the associated domains.
Clock domains will be linked to voltage domains and thus allow separate clock,
but shared voltage lines.
Currently all the valid performance-level updates are performed with a fixed
transition latency as specified for the domain.
Config file example:
...
vd = VoltageDomain(voltage = ['1V','0.95V','0.90V','0.85V'])
tsys.cluster1.clk_domain.clock = ['1GHz','700MHz','400MHz','230MHz']
tsys.cluster2.clk_domain.clock = ['1GHz','700MHz','400MHz','230MHz']
tsys.cluster1.clk_domain.domain_id = 0
tsys.cluster2.clk_domain.domain_id = 1
tsys.cluster1.clk_domain.voltage_domain = vd
tsys.cluster2.clk_domain.voltage_domain = vd
tsys.dvfs_handler.domains = [tsys.cluster1.clk_domain,
tsys.cluster2.clk_domain]
tsys.dvfs_handler.enable = True
Diffstat (limited to 'src/sim/clock_domain.cc')
-rw-r--r-- | src/sim/clock_domain.cc | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/src/sim/clock_domain.cc b/src/sim/clock_domain.cc index 0d1836e83..746ef12fd 100644 --- a/src/sim/clock_domain.cc +++ b/src/sim/clock_domain.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 ARM Limited + * Copyright (c) 2013-2014 ARM Limited * Copyright (c) 2013 Cornell University * All rights reserved * @@ -39,8 +39,12 @@ * Akash Bagdia * Andreas Hansson * Christopher Torng + * Stephan Diestelhorst */ +#include <algorithm> +#include <functional> + #include "debug/ClockDomain.hh" #include "params/ClockDomain.hh" #include "params/DerivedClockDomain.hh" @@ -70,9 +74,37 @@ ClockDomain::voltage() const } SrcClockDomain::SrcClockDomain(const Params *p) : - ClockDomain(p, p->voltage_domain) + ClockDomain(p, p->voltage_domain), + freqOpPoints(p->clock), + _domainID(p->domain_id), + _perfLevel(p->init_perf_level) { - clockPeriod(p->clock); + VoltageDomain *vdom = p->voltage_domain; + + fatal_if(freqOpPoints.empty(), "DVFS: Empty set of frequencies for "\ + "domain %d %s\n", _domainID, name()); + + fatal_if(!vdom, "DVFS: Empty voltage domain specified for "\ + "domain %d %s\n", _domainID, name()); + + fatal_if((vdom->numVoltages() > 1) && + (vdom->numVoltages() != freqOpPoints.size()), + "DVFS: Number of frequency and voltage scaling points do "\ + "not match: %d:%d ID: %d %s.\n", vdom->numVoltages(), + freqOpPoints.size(), _domainID, name()); + + // Frequency (& voltage) points should be declared in descending order, + // NOTE: Frequency is inverted to ticks, so checking for ascending ticks + fatal_if(!std::is_sorted(freqOpPoints.begin(), freqOpPoints.end()), + "DVFS: Frequency operation points not in descending order for "\ + "domain with ID %d\n", _domainID); + + fatal_if(_perfLevel >= freqOpPoints.size(), "DVFS: Initial DVFS point %d "\ + "is outside of list for Domain ID: %d\n", _perfLevel, _domainID); + + clockPeriod(freqOpPoints[_perfLevel]); + + vdom->registerSrcClockDom(this); } void @@ -99,6 +131,40 @@ SrcClockDomain::clockPeriod(Tick clock_period) } } +void +SrcClockDomain::perfLevel(PerfLevel perf_level) +{ + assert(validPerfLevel(perf_level)); + + DPRINTF(ClockDomain, "DVFS: Switching performance level of domain %s "\ + "(id: %d) from %d to %d\n", name(), domainID(), _perfLevel, + perf_level); + + _perfLevel = perf_level; + + // Signal the voltage domain that we have changed our perf level so that the + // voltage domain can recompute its performance level + voltageDomain()->sanitiseVoltages(); + + // Integrated switching of the actual clock value, too + clockPeriod(clkPeriodAtPerfLevel()); +} + +void +SrcClockDomain::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(_perfLevel); + ClockDomain::serialize(os); +} + +void +SrcClockDomain::unserialize(Checkpoint *cp, const std::string §ion) +{ + ClockDomain::unserialize(cp, section); + UNSERIALIZE_SCALAR(_perfLevel); + perfLevel(_perfLevel); +} + SrcClockDomain * SrcClockDomainParams::create() { |