diff options
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() { |