clocked_object.hh (11800:54436a1784dc) clocked_object.hh (14162:6b811c4fdde6)
1/*
2 * Copyright (c) 2012-2013, 2015-2016 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

--- 64 unchanged lines hidden (view full) ---

73 // The cycle counter value corresponding to the current value of
74 // 'tick'
75 mutable Cycles cycle;
76
77 /**
78 * Align cycle and tick to the next clock edge if not already done. When
79 * complete, tick must be at least curTick().
80 */
1/*
2 * Copyright (c) 2012-2013, 2015-2016 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

--- 64 unchanged lines hidden (view full) ---

73 // The cycle counter value corresponding to the current value of
74 // 'tick'
75 mutable Cycles cycle;
76
77 /**
78 * Align cycle and tick to the next clock edge if not already done. When
79 * complete, tick must be at least curTick().
80 */
81 void update() const
81 void
82 update() const
82 {
83 // both tick and cycle are up-to-date and we are done, note
84 // that the >= is important as it captures cases where tick
85 // has already passed curTick()
86 if (tick >= curTick())
87 return;
88
89 // optimise for the common case and see if the tick should be

--- 40 unchanged lines hidden (view full) ---

130 */
131 virtual ~Clocked() { }
132
133 /**
134 * Reset the object's clock using the current global tick value. Likely
135 * to be used only when the global clock is reset. Currently, this done
136 * only when Ruby is done warming up the memory system.
137 */
83 {
84 // both tick and cycle are up-to-date and we are done, note
85 // that the >= is important as it captures cases where tick
86 // has already passed curTick()
87 if (tick >= curTick())
88 return;
89
90 // optimise for the common case and see if the tick should be

--- 40 unchanged lines hidden (view full) ---

131 */
132 virtual ~Clocked() { }
133
134 /**
135 * Reset the object's clock using the current global tick value. Likely
136 * to be used only when the global clock is reset. Currently, this done
137 * only when Ruby is done warming up the memory system.
138 */
138 void resetClock() const
139 void
140 resetClock() const
139 {
140 Cycles elapsedCycles(divCeil(curTick(), clockPeriod()));
141 cycle = elapsedCycles;
142 tick = elapsedCycles * clockPeriod();
143 }
144
145 public:
146
147 /**
148 * Update the tick to the current tick.
141 {
142 Cycles elapsedCycles(divCeil(curTick(), clockPeriod()));
143 cycle = elapsedCycles;
144 tick = elapsedCycles * clockPeriod();
145 }
146
147 public:
148
149 /**
150 * Update the tick to the current tick.
149 *
150 */
151 */
151 inline void updateClockPeriod() const
152 {
153 update();
154 }
152 void updateClockPeriod() const { update(); }
155
156 /**
157 * Determine the tick when a cycle begins, by default the current one, but
158 * the argument also enables the caller to determine a future cycle. When
159 * curTick() is on a clock edge, the number of cycles in the parameter is
160 * added to curTick() to be returned. When curTick() is not aligned to a
161 * clock edge, the number of cycles in the parameter is added to the next
162 * clock edge.
163 *
164 * @param cycles The number of cycles into the future
165 *
166 * @return The start tick when the requested clock edge occurs. Precisely,
167 * this tick can be
168 * curTick() + [0, clockPeriod()) + clockPeriod() * cycles
169 */
153
154 /**
155 * Determine the tick when a cycle begins, by default the current one, but
156 * the argument also enables the caller to determine a future cycle. When
157 * curTick() is on a clock edge, the number of cycles in the parameter is
158 * added to curTick() to be returned. When curTick() is not aligned to a
159 * clock edge, the number of cycles in the parameter is added to the next
160 * clock edge.
161 *
162 * @param cycles The number of cycles into the future
163 *
164 * @return The start tick when the requested clock edge occurs. Precisely,
165 * this tick can be
166 * curTick() + [0, clockPeriod()) + clockPeriod() * cycles
167 */
170 inline Tick clockEdge(Cycles cycles = Cycles(0)) const
168 Tick
169 clockEdge(Cycles cycles=Cycles(0)) const
171 {
172 // align tick to the next clock edge
173 update();
174
175 // figure out when this future cycle is
176 return tick + clockPeriod() * cycles;
177 }
178
179 /**
180 * Determine the current cycle, corresponding to a tick aligned to
181 * a clock edge.
182 *
183 * @return When curTick() is on a clock edge, return the Cycle corresponding
184 * to that clock edge. When curTick() is not on a clock edge, return the
185 * Cycle corresponding to the next clock edge.
186 */
170 {
171 // align tick to the next clock edge
172 update();
173
174 // figure out when this future cycle is
175 return tick + clockPeriod() * cycles;
176 }
177
178 /**
179 * Determine the current cycle, corresponding to a tick aligned to
180 * a clock edge.
181 *
182 * @return When curTick() is on a clock edge, return the Cycle corresponding
183 * to that clock edge. When curTick() is not on a clock edge, return the
184 * Cycle corresponding to the next clock edge.
185 */
187 inline Cycles curCycle() const
186 Cycles
187 curCycle() const
188 {
189 // align cycle to the next clock edge.
190 update();
191
192 return cycle;
193 }
194
195 /**
196 * Based on the clock of the object, determine the start tick of the first
197 * cycle that is at least one cycle in the future. When curTick() is at the
198 * current cycle edge, this returns the next clock edge. When calling this
199 * during the middle of a cycle, this returns 2 clock edges in the future.
200 *
201 * @return The start tick of the first cycle that is at least one cycle in
202 * the future. Precisely, the returned tick can be in the range
203 * curTick() + [clockPeriod(), 2 * clockPeriod())
204 */
188 {
189 // align cycle to the next clock edge.
190 update();
191
192 return cycle;
193 }
194
195 /**
196 * Based on the clock of the object, determine the start tick of the first
197 * cycle that is at least one cycle in the future. When curTick() is at the
198 * current cycle edge, this returns the next clock edge. When calling this
199 * during the middle of a cycle, this returns 2 clock edges in the future.
200 *
201 * @return The start tick of the first cycle that is at least one cycle in
202 * the future. Precisely, the returned tick can be in the range
203 * curTick() + [clockPeriod(), 2 * clockPeriod())
204 */
205 Tick nextCycle() const
206 { return clockEdge(Cycles(1)); }
205 Tick nextCycle() const { return clockEdge(Cycles(1)); }
207
206
208 inline uint64_t frequency() const
209 {
210 return SimClock::Frequency / clockPeriod();
211 }
207 uint64_t frequency() const { return SimClock::Frequency / clockPeriod(); }
212
208
213 inline Tick clockPeriod() const
214 {
215 return clockDomain.clockPeriod();
216 }
209 Tick clockPeriod() const { return clockDomain.clockPeriod(); }
217
210
218 inline double voltage() const
211 double voltage() const { return clockDomain.voltage(); }
212
213 Cycles
214 ticksToCycles(Tick t) const
219 {
215 {
220 return clockDomain.voltage();
216 return Cycles(divCeil(t, clockPeriod()));
221 }
222
217 }
218
223 inline Cycles ticksToCycles(Tick t) const
224 { return Cycles(divCeil(t, clockPeriod())); }
225
226 inline Tick cyclesToTicks(Cycles c) const
227 { return clockPeriod() * c; }
219 Tick cyclesToTicks(Cycles c) const { return clockPeriod() * c; }
228};
229
230/**
231 * The ClockedObject class extends the SimObject with a clock and
232 * accessor functions to relate ticks to the cycles of the object.
233 */
220};
221
222/**
223 * The ClockedObject class extends the SimObject with a clock and
224 * accessor functions to relate ticks to the cycles of the object.
225 */
234class ClockedObject
235 : public SimObject, public Clocked
226class ClockedObject : public SimObject, public Clocked
236{
237 public:
238 ClockedObject(const ClockedObjectParams *p);
239
240 /** Parameters of ClockedObject */
241 typedef ClockedObjectParams Params;
227{
228 public:
229 ClockedObject(const ClockedObjectParams *p);
230
231 /** Parameters of ClockedObject */
232 typedef ClockedObjectParams Params;
242 const Params* params() const
243 { return reinterpret_cast<const Params*>(_params); }
233 const Params *
234 params() const
235 {
236 return reinterpret_cast<const Params*>(_params);
237 }
244
245 void serialize(CheckpointOut &cp) const override;
246 void unserialize(CheckpointIn &cp) override;
247
238
239 void serialize(CheckpointOut &cp) const override;
240 void unserialize(CheckpointIn &cp) override;
241
248 inline Enums::PwrState pwrState() const
249 { return _currPwrState; }
242 Enums::PwrState pwrState() const { return _currPwrState; }
250
243
251 inline std::string pwrStateName() const
252 { return Enums::PwrStateStrings[_currPwrState]; }
244 std::string
245 pwrStateName() const
246 {
247 return Enums::PwrStateStrings[_currPwrState];
248 }
253
254 /** Returns the percentage residency for each power state */
255 std::vector<double> pwrStateWeights() const;
256
257 /**
258 * Record stats values like state residency by computing the time
259 * difference from previous update. Also, updates the previous evaluation
260 * tick once all stats are recorded.

--- 29 unchanged lines hidden ---
249
250 /** Returns the percentage residency for each power state */
251 std::vector<double> pwrStateWeights() const;
252
253 /**
254 * Record stats values like state residency by computing the time
255 * difference from previous update. Also, updates the previous evaluation
256 * tick once all stats are recorded.

--- 29 unchanged lines hidden ---