diff options
author | Stephan Diestelhorst <stephan.diestelhorst@arm.com> | 2014-08-12 19:00:44 +0100 |
---|---|---|
committer | Stephan Diestelhorst <stephan.diestelhorst@arm.com> | 2014-08-12 19:00:44 +0100 |
commit | 16351ba8d6b98e4dc0012cfc4083fe93ec6d76ce (patch) | |
tree | 59c73b35dd747121f962e03f7d43a45a824ced9a | |
parent | 65aaf62714f783073b994f89fddf8558332607e8 (diff) | |
download | gem5-16351ba8d6b98e4dc0012cfc4083fe93ec6d76ce.tar.xz |
energy: Tighter checking of levels for DFS systems
There are cases where users might by accident / intention specify less voltage
operating points thatn frequency points. We consider one of these cases
special: giving only a single voltage to a voltage domain effectively renders
it as a static domain. This patch adds additional logic in the auxiliary parts
of the functionality to handle these cases properly (simple driver asking for
N>1 operating levels, we should return the same voltage for all of them) and
adds error checking code in the voltage domain.
-rw-r--r-- | src/sim/dvfs_handler.hh | 30 | ||||
-rw-r--r-- | src/sim/voltage_domain.hh | 4 |
2 files changed, 32 insertions, 2 deletions
diff --git a/src/sim/dvfs_handler.hh b/src/sim/dvfs_handler.hh index 3ff08115a..a8b78d08b 100644 --- a/src/sim/dvfs_handler.hh +++ b/src/sim/dvfs_handler.hh @@ -137,7 +137,15 @@ class DVFSHandler : public SimObject */ Tick clkPeriodAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const { - return findDomain(domain_id)->clkPeriodAtPerfLevel(perf_level); + SrcClockDomain *d = findDomain(domain_id); + assert(d); + PerfLevel n = d->numPerfLevels(); + if (perf_level < n) + return d->clkPeriodAtPerfLevel(perf_level); + + warn("DVFSHandler %s reads illegal frequency level %u from "\ + "SrcClockDomain %s. Returning 0\n", name(), perf_level, d->name()); + return Tick(0); } /** @@ -150,7 +158,25 @@ class DVFSHandler : public SimObject */ double voltageAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const { - return findDomain(domain_id)->voltageDomain()->voltage(perf_level); + VoltageDomain *d = findDomain(domain_id)->voltageDomain(); + assert(d); + PerfLevel n = d->numVoltages(); + if (perf_level < n) + return d->voltage(perf_level); + + // Request outside of the range of the voltage domain + if (n == 1) { + DPRINTF(DVFS, "DVFS: Request for perf-level %i for single-point "\ + "voltage domain %s. Returning voltage at level 0: %.2f "\ + "V\n", perf_level, d->name(), d->voltage(0)); + // Special case for single point voltage domain -> same voltage for + // all points + return d->voltage(0); + } + + warn("DVFSHandler %s reads illegal voltage level %u from "\ + "VoltageDomain %s. Returning 0 V\n", name(), perf_level, d->name()); + return 0.; } /** diff --git a/src/sim/voltage_domain.hh b/src/sim/voltage_domain.hh index 9ffbe7bbc..ab96abad8 100644 --- a/src/sim/voltage_domain.hh +++ b/src/sim/voltage_domain.hh @@ -77,6 +77,10 @@ class VoltageDomain : public SimObject */ double voltage(PerfLevel perf_level) const { + chatty_assert(perf_level < numVoltages(), "VoltageDomain %s "\ + "request for voltage perf level %u is outside "\ + "of numVoltages %u", name(), perf_level, + numVoltages()); return voltageOpPoints[perf_level]; } |