summaryrefslogtreecommitdiff
path: root/src/sim/clock_domain.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/clock_domain.cc')
-rw-r--r--src/sim/clock_domain.cc72
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 &section)
+{
+ ClockDomain::unserialize(cp, section);
+ UNSERIALIZE_SCALAR(_perfLevel);
+ perfLevel(_perfLevel);
+}
+
SrcClockDomain *
SrcClockDomainParams::create()
{