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 * Christopher Torng 41 * Stephan Diestelhorst 42 */ 43 44/** 45 * @file 46 * ClockDomain declarations. 47 */ 48 49#ifndef __SIM_CLOCK_DOMAIN_HH__ 50#define __SIM_CLOCK_DOMAIN_HH__ 51 52#include <algorithm> 53 54#include "base/statistics.hh" 55#include "params/ClockDomain.hh" 56#include "params/DerivedClockDomain.hh" 57#include "params/SrcClockDomain.hh" 58#include "sim/sim_object.hh" 59 60/** 61 * Forward declaration 62 */ 63class DerivedClockDomain; 64class VoltageDomain; 65class Clocked; 66 67/** 68 * The ClockDomain provides clock to group of clocked objects bundled 69 * under the same clock domain. The clock domains, in turn, are 70 * grouped into voltage domains. The clock domains provide support for 71 * a hierarchial structure with source and derived domains. 72 */ 73class ClockDomain : public SimObject 74{ 75 76 private: 77 78 /** 79 * Stat to report clock period of clock domain 80 */ 81 Stats::Value currentClock; 82 83 protected: 84 85 /** 86 * Pre-computed clock period in ticks. This is populated by the 87 * inheriting classes based on how their period is determined. 88 */ 89 Tick _clockPeriod; 90 91 /** 92 * Voltage domain this clock domain belongs to 93 */ 94 VoltageDomain *_voltageDomain; 95 96 /** 97 * Pointers to potential derived clock domains so we can propagate 98 * changes. 99 */ 100 std::vector<DerivedClockDomain*> children; 101 102 /** 103 * Pointers to members of this clock domain, so that when the clock 104 * period changes, we can update each member's tick. 105 */ 106 std::vector<Clocked *> members; 107 108 public: 109 110 typedef ClockDomainParams Params; 111 ClockDomain(const Params *p, VoltageDomain *voltage_domain) : 112 SimObject(p), 113 _clockPeriod(0), 114 _voltageDomain(voltage_domain) {} 115 116 void regStats(); 117 118 /** 119 * Get the clock period. 120 * 121 * @return Clock period in ticks 122 */ 123 Tick clockPeriod() const { return _clockPeriod; } 124 125 /** 126 * Register a Clocked object with this ClockDomain. 127 * 128 * @param Clocked to add as a member 129 */ 130 void registerWithClockDomain(Clocked *c) 131 { 132 assert(c != NULL); 133 assert(std::find(members.begin(), members.end(), c) == members.end()); 134 members.push_back(c); 135 } 136 137 /** 138 * Get the voltage domain. 139 * 140 * @return Voltage domain this clock domain belongs to 141 */ 142 inline VoltageDomain *voltageDomain() const { return _voltageDomain; } 143 144 145 /** 146 * Get the current voltage this clock domain operates at. 147 * 148 * @return Voltage applied to the clock domain 149 */ 150 double voltage() const; 151 152 /** 153 * Add a derived domain. 154 * 155 * @param Derived domain to add as a child 156 */ 157 void addDerivedDomain(DerivedClockDomain *clock_domain) 158 { children.push_back(clock_domain); } 159 160}; 161 162/** 163 * The source clock domains provides the notion of a clock domain that is 164 * connected to a tunable clock source. It maintains the clock period and 165 * provides methods for setting/getting the clock and configuration parameters 166 * for clock domain that handler is going to manage. This includes frequency 167 * values at various performance levels, domain id, and current performance 168 * level. Note that a performance level as requested by the software corresponds 169 * to one of the frequency operational points the domain can operate at. 170 */ 171class SrcClockDomain : public ClockDomain 172{ 173 174 public: 175 176 typedef SrcClockDomainParams Params; 177 SrcClockDomain(const Params *p); 178 179 /** 180 * Set new clock value 181 * @param clock The new clock period in ticks 182 */ 183 void clockPeriod(Tick clock_period); 184 185 // Explicitly import the otherwise hidden clockPeriod 186 using ClockDomain::clockPeriod; 187 188 typedef int32_t DomainID; 189 static const DomainID emptyDomainID = -1; 190 191 /** 192 * @return the domainID of the domain 193 */ 194 uint32_t domainID() const { return _domainID; } 195 196 typedef uint32_t PerfLevel; 197 /** 198 * Checks whether the performance level requested exists in the current 199 * domain configuration 200 * 201 * @param the target performance level of the domain 202 * 203 * @return validity status of the given performance level 204 */ 205 bool validPerfLevel(PerfLevel perf_level) const { 206 return perf_level < numPerfLevels(); 207 } 208 209 /** 210 * Sets the current performance level of the domain 211 * 212 * @param perf_level the target performance level 213 */ 214 void perfLevel(PerfLevel perf_level); 215 216 /** 217 * @return the current performance level of the domain 218 */ 219 PerfLevel perfLevel() const { return _perfLevel; } 220 221 /** 222 * Get the number of available performance levels for this clock domain. 223 * 224 * @return Number of perf levels configured for this domain. 225 */ 226 PerfLevel numPerfLevels() const {return freqOpPoints.size();} 227 228 /** 229 * @returns the clock period (expressed in ticks) for the current 230 * performance level 231 */ 232 Tick clkPeriodAtPerfLevel() const { return freqOpPoints[perfLevel()]; } 233 234 Tick clkPeriodAtPerfLevel(PerfLevel perf_level) const 235 { 236 assert(validPerfLevel(perf_level)); 237 return freqOpPoints[perf_level]; 238 } 239 240 void startup() override; 241 242 void serialize(CheckpointOut &cp) const override; 243 void unserialize(CheckpointIn &cp) override; 244 245 private: 246 /** 247 * Inform other components about the changed performance level 248 */ 249 void signalPerfLevelUpdate(); 250 251 /** 252 * List of possible frequency operational points, should be in 253 * descending order 254 * An empty list corresponds to default frequency specified for its 255 * clock domain, overall implying NO DVFS 256 */ 257 const std::vector<Tick> freqOpPoints; 258 259 /** 260 * Software recognizable id number for the domain, should be unique for 261 * each domain 262 */ 263 const uint32_t _domainID; 264 265 /** 266 * Current performance level the domain is set to. 267 * The performance level corresponds to one selected frequency (and related 268 * voltage) from the supplied list of frequencies, with perfLevel = 0 being 269 * the fastest performance state. 270 */ 271 PerfLevel _perfLevel; 272}; 273 274/** 275 * The derived clock domains provides the notion of a clock domain 276 * that is connected to a parent clock domain that can either be a 277 * source clock domain or a derived clock domain. It maintains the 278 * clock divider and provides methods for getting the clock. 279 */ 280class DerivedClockDomain: public ClockDomain 281{ 282 283 public: 284 285 typedef DerivedClockDomainParams Params; 286 DerivedClockDomain(const Params *p); 287 288 /** 289 * Called by the parent clock domain to propagate changes. This 290 * also involves propagating the change further to any children of 291 * the derived domain itself. 292 */ 293 void updateClockPeriod(); 294 295 private: 296 297 /** 298 * Reference to the parent clock domain this clock domain derives 299 * its clock period from 300 */ 301 ClockDomain &parent; 302 303 /** 304 * Local clock divider of the domain 305 */ 306 const uint64_t clockDivider; 307}; 308 309#endif 310