gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
clock_domain.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014 ARM Limited
3  * Copyright (c) 2013 Cornell University
4  * All rights reserved
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions are
17  * met: redistributions of source code must retain the above copyright
18  * notice, this list of conditions and the following disclaimer;
19  * redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution;
22  * neither the name of the copyright holders nor the names of its
23  * contributors may be used to endorse or promote products derived from
24  * this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Authors: Vasileios Spiliopoulos
39  * Akash Bagdia
40  * Andreas Hansson
41  * Christopher Torng
42  * Stephan Diestelhorst
43  */
44 
45 #include "sim/clock_domain.hh"
46 
47 #include <algorithm>
48 #include <functional>
49 
50 #include "base/trace.hh"
51 #include "debug/ClockDomain.hh"
52 #include "params/ClockDomain.hh"
53 #include "params/DerivedClockDomain.hh"
54 #include "params/SrcClockDomain.hh"
55 #include "sim/clocked_object.hh"
56 #include "sim/voltage_domain.hh"
57 
58 void
60 {
62 
63  using namespace Stats;
64 
65  // Expose the current clock period as a stat for observability in
66  // the dumps
69  .name(params()->name + ".clock")
70  .desc("Clock period in ticks")
71  ;
72 }
73 
74 double
76 {
77  return _voltageDomain->voltage();
78 }
79 
81  ClockDomain(p, p->voltage_domain),
82  freqOpPoints(p->clock),
83  _domainID(p->domain_id),
84  _perfLevel(p->init_perf_level)
85 {
86  VoltageDomain *vdom = p->voltage_domain;
87 
88  fatal_if(freqOpPoints.empty(), "DVFS: Empty set of frequencies for "\
89  "domain %d %s\n", _domainID, name());
90 
91  fatal_if(!vdom, "DVFS: Empty voltage domain specified for "\
92  "domain %d %s\n", _domainID, name());
93 
94  fatal_if((vdom->numVoltages() > 1) &&
95  (vdom->numVoltages() != freqOpPoints.size()),
96  "DVFS: Number of frequency and voltage scaling points do "\
97  "not match: %d:%d ID: %d %s.\n", vdom->numVoltages(),
98  freqOpPoints.size(), _domainID, name());
99 
100  // Frequency (& voltage) points should be declared in descending order,
101  // NOTE: Frequency is inverted to ticks, so checking for ascending ticks
102  fatal_if(!std::is_sorted(freqOpPoints.begin(), freqOpPoints.end()),
103  "DVFS: Frequency operation points not in descending order for "\
104  "domain with ID %d\n", _domainID);
105 
106  fatal_if(_perfLevel >= freqOpPoints.size(), "DVFS: Initial DVFS point %d "\
107  "is outside of list for Domain ID: %d\n", _perfLevel, _domainID);
108 
110 
111  vdom->registerSrcClockDom(this);
112 }
113 
114 void
116 {
117  if (clock_period == 0) {
118  fatal("%s has a clock period of zero\n", name());
119  }
120 
121  // Align all members to the current tick
122  for (auto m = members.begin(); m != members.end(); ++m) {
123  (*m)->updateClockPeriod();
124  }
125 
126  _clockPeriod = clock_period;
127 
129  "Setting clock period to %d ticks for source clock %s\n",
130  _clockPeriod, name());
131 
132  // inform any derived clocks they need to updated their period
133  for (auto c = children.begin(); c != children.end(); ++c) {
134  (*c)->updateClockPeriod();
135  }
136 }
137 
138 void
140 {
141  assert(validPerfLevel(perf_level));
142 
143  if (perf_level == _perfLevel) {
144  // Silently ignore identical overwrites
145  return;
146  }
147 
148  DPRINTF(ClockDomain, "DVFS: Switching performance level of domain %s "\
149  "(id: %d) from %d to %d\n", name(), domainID(), _perfLevel,
150  perf_level);
151 
152  _perfLevel = perf_level;
153 
155 }
156 
158 {
159  // Signal the voltage domain that we have changed our perf level so that the
160  // voltage domain can recompute its performance level
162 
163  // Integrated switching of the actual clock value, too
165 }
166 
167 void
169 {
172 }
173 
174 void
176 {
179 }
180 
181 void
183 {
184  // Perform proper clock update when all related components have been
185  // created (i.e. after unserialization / object creation)
187 }
188 
190 SrcClockDomainParams::create()
191 {
192  return new SrcClockDomain(this);
193 }
194 
196  ClockDomain(p, p->clk_domain->voltageDomain()),
197  parent(*p->clk_domain),
198  clockDivider(p->clk_divider)
199 {
200  // Ensure that clock divider setting works as frequency divider and never
201  // work as frequency multiplier
202  if (clockDivider < 1) {
203  fatal("Clock divider param cannot be less than 1");
204  }
205 
206  // let the parent keep track of this derived domain so that it can
207  // propagate changes
208  parent.addDerivedDomain(this);
209 
210  // update our clock period based on the parents clock
212 }
213 
214 void
216 {
217  // Align all members to the current tick
218  for (auto m = members.begin(); m != members.end(); ++m) {
219  (*m)->updateClockPeriod();
220  }
221 
222  // recalculate the clock period, relying on the fact that changes
223  // propagate downwards in the tree
225 
227  "Setting clock period to %d ticks for derived clock %s\n",
228  _clockPeriod, name());
229 
230  // inform any derived clocks
231  for (auto c = children.begin(); c != children.end(); ++c) {
232  (*c)->updateClockPeriod();
233  }
234 }
235 
237 DerivedClockDomainParams::create()
238 {
239  return new DerivedClockDomain(this);
240 }
uint32_t domainID() const
#define DPRINTF(x,...)
Definition: trace.hh:212
void registerSrcClockDom(SrcClockDomain *src_clock_dom)
Register a SrcClockDomain with this voltage domain.
Bitfield< 0 > m
Definition: miscregs.hh:1577
void addDerivedDomain(DerivedClockDomain *clock_domain)
Add a derived domain.
void startup() override
startup() is the final initialization call before simulation.
void signalPerfLevelUpdate()
Inform other components about the changed performance level.
const Params * params() const
Definition: sim_object.hh:111
double voltage() const
Get the current voltage this clock domain operates at.
Definition: clock_domain.cc:75
const uint64_t clockDivider
Local clock divider of the domain.
VoltageDomain * _voltageDomain
Voltage domain this clock domain belongs to.
Definition: clock_domain.hh:94
ClockDomainParams Params
virtual void regStats()
Register statistics for this object.
Definition: sim_object.cc:105
Derived & scalar(T &value)
Definition: statistics.hh:815
VoltageDomain * voltageDomain() const
Get the voltage domain.
const uint32_t _domainID
Software recognizable id number for the domain, should be unique for each domain. ...
bool validPerfLevel(PerfLevel perf_level) const
Checks whether the performance level requested exists in the current domain configuration.
uint32_t PerfLevel
The derived clock domains provides the notion of a clock domain that is connected to a parent clock d...
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: sim_object.hh:209
const std::vector< Tick > freqOpPoints
List of possible frequency operational points, should be in descending order An empty list correspond...
bool sanitiseVoltages()
Recomputes the highest (fastest, i.e., numerically lowest) requested performance level of all associa...
uint32_t numVoltages() const
uint64_t Tick
Tick count type.
Definition: types.hh:63
ClockedObject declaration and implementation.
#define fatal(...)
Definition: misc.hh:163
double voltage() const
Get the current voltage.
ClockDomain & parent
Reference to the parent clock domain this clock domain derives its clock period from.
ClockDomain declarations.
Stats::Value currentClock
Stat to report clock period of clock domain.
Definition: clock_domain.hh:81
void updateClockPeriod()
Called by the parent clock domain to propagate changes.
void serialize(CheckpointOut &cp) const override
Serialize an object.
A VoltageDomain is used to group clock domains that operate under the same voltage.
SrcClockDomain(const Params *p)
Definition: clock_domain.cc:80
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
The source clock domains provides the notion of a clock domain that is connected to a tunable clock s...
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:254
virtual const std::string name() const
Definition: sim_object.hh:117
Bitfield< 29 > c
Definition: miscregs.hh:1365
std::vector< DerivedClockDomain * > children
Pointers to potential derived clock domains so we can propagate changes.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
The ClockDomain provides clock to group of clocked objects bundled under the same clock domain...
Definition: clock_domain.hh:73
std::vector< Clocked * > members
Pointers to members of this clock domain, so that when the clock period changes, we can update each m...
std::ostream CheckpointOut
Definition: serialize.hh:67
PerfLevel perfLevel() const
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: sim_object.hh:210
Tick clkPeriodAtPerfLevel() const
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:287
DerivedClockDomain(const Params *p)
Tick _clockPeriod
Pre-computed clock period in ticks.
Definition: clock_domain.hh:89
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
Bitfield< 0 > p
void regStats()
Register statistics for this object.
Definition: clock_domain.cc:59
PerfLevel _perfLevel
Current performance level the domain is set to.
Tick clockPeriod() const
Get the clock period.

Generated on Fri Jun 9 2017 13:03:51 for gem5 by doxygen 1.8.6