gem5  v20.1.0.0
sc_time.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Google, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met: redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer;
8  * redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution;
11  * neither the name of the copyright holders nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <cmath>
29 #include <cstring>
30 #include <sstream>
31 #include <vector>
32 
33 #include "base/types.hh"
34 #include "sim/core.hh"
35 #include "systemc/core/time.hh"
40 
41 namespace sc_core
42 {
43 
44 namespace
45 {
46 
47 void
48 set(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu)
49 {
50  if (d != 0)
52 
54  // Accellera claims there is a linux bug, and that these next two
55  // lines work around them.
56  volatile double tmp = d * scale + 0.5;
57  *time = sc_time::from_value(static_cast<uint64_t>(tmp));
58 }
59 
60 double defaultUnit = 1.0e-9;
61 
62 } // anonymous namespace
63 
65 
67 {
68  val = 0;
69  set(this, d, tu);
70 }
71 
73 {
74  val = t.val;
75 }
76 
77 sc_time::sc_time(double d, const char *unit)
78 {
80  for (tu = SC_FS; tu <= SC_SEC; tu = (sc_time_unit)(tu + 1)) {
81  if (strcmp(unit, sc_gem5::TimeUnitNames[tu]) == 0 ||
82  strcmp(unit, sc_gem5::TimeUnitConstantNames[tu]) == 0) {
83  break;
84  }
85  }
86 
87  if (tu > SC_SEC) {
88  SC_REPORT_ERROR(SC_ID_TIME_CONVERSION_FAILED_,"invalid unit given");
89  val = 0;
90  return;
91  }
92  set(this, d, tu);
93 }
94 
95 sc_time::sc_time(double d, bool scale)
96 {
97  double scaler = scale ? defaultUnit : SimClock::Float::Hz;
98  set(this, d * scaler, SC_SEC);
99 }
100 
102 {
103  double scaler = scale ? defaultUnit : SimClock::Float::Hz;
104  set(this, static_cast<double>(v) * scaler, SC_SEC);
105 }
106 
107 sc_time &
109 {
110  val = t.val;
111  return *this;
112 }
113 
116 {
117  return val;
118 }
119 
120 double
122 {
123  return static_cast<double>(val);
124 }
125 double
127 {
128  return to_double() * SimClock::Float::Hz;
129 }
130 
131 const std::string
133 {
134  std::ostringstream ss;
135  print(ss);
136  return ss.str();
137 }
138 
139 bool
141 {
142  return val == t.val;
143 }
144 
145 bool
147 {
148  return val != t.val;
149 }
150 
151 bool
153 {
154  return val < t.val;
155 }
156 
157 bool
159 {
160  return val <= t.val;
161 }
162 
163 bool
165 {
166  return val > t.val;
167 }
168 
169 bool
171 {
172  return val >= t.val;
173 }
174 
175 sc_time &
177 {
178  val += t.val;
179  return *this;
180 }
181 
182 sc_time &
184 {
185  val -= t.val;
186  return *this;
187 }
188 
189 sc_time &
191 {
192  val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5);
193  return *this;
194 }
195 
196 sc_time &
198 {
199  val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5);
200  return *this;
201 }
202 
203 void
204 sc_time::print(std::ostream &os) const
205 {
206  os << sc_time_tuple(*this).to_string();
207 }
208 
209 sc_time
211 {
212  if (u)
214  sc_time t;
215  t.val = u;
216  return t;
217 }
218 
219 sc_time
221 {
222  sc_time t;
223  set(&t, d, SC_SEC);
224  return t;
225 }
226 
227 sc_time
228 sc_time::from_string(const char *str)
229 {
230  char *end = nullptr;
231 
232  double d = str ? std::strtod(str, &end) : 0.0;
233  if (str == end || d < 0.0) {
234  SC_REPORT_ERROR(SC_ID_TIME_CONVERSION_FAILED_, "invalid value given");
235  return SC_ZERO_TIME;
236  }
237 
238  while (*end && std::isspace(*end))
239  end++;
240 
241  return sc_time(d, end);
242 }
243 
244 const sc_time
245 operator + (const sc_time &a, const sc_time &b)
246 {
247  return sc_time::from_value(a.value() + b.value());
248 }
249 
250 const sc_time
251 operator - (const sc_time &a, const sc_time &b)
252 {
253  return sc_time::from_value(a.value() - b.value());
254 }
255 
256 const sc_time
257 operator * (const sc_time &t, double d)
258 {
259  volatile double tmp = static_cast<double>(t.value()) * d + 0.5;
260  return sc_time::from_value(static_cast<int64_t>(tmp));
261 }
262 
263 const sc_time
264 operator * (double d, const sc_time &t)
265 {
266  volatile double tmp = d * static_cast<double>(t.value()) + 0.5;
267  return sc_time::from_value(static_cast<int64_t>(tmp));
268 }
269 
270 const sc_time
271 operator / (const sc_time &t, double d)
272 {
273  volatile double tmp = static_cast<double>(t.value()) / d + 0.5;
274  return sc_time::from_value(static_cast<int64_t>(tmp));
275 }
276 
277 double
278 operator / (const sc_time &t1, const sc_time &t2)
279 {
280  return t1.to_double() / t2.to_double();
281 }
282 
283 std::ostream &
284 operator << (std::ostream &os, const sc_time &t)
285 {
286  t.print(os);
287  return os;
288 }
289 
291 
292 void
294 {
295  if (d <= 0.0)
296  SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "value not positive");
297 
298  double dummy;
299  if (modf(log10(d), &dummy) != 0.0) {
301  "value not a power of ten");
302  }
303  if (sc_is_running())
304  SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "simulation running");
305 
306  static bool specified = false;
307  if (specified)
308  SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "already specified");
309 
310  // This won't detect the timescale being fixed outside of systemc, but
311  // it's at least some protection.
312  if (clockFrequencyFixed()) {
314  "sc_time object(s) constructed");
315  }
316 
317  double seconds = d * sc_gem5::TimeUnitScale[tu];
318  if (seconds < sc_gem5::TimeUnitScale[SC_FS])
319  SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "value smaller than 1 fs");
320 
321  if (seconds > defaultUnit) {
323  defaultUnit = seconds;
324  }
325 
326  // Get rid of fractional parts of d.
327  while (d < 1.0 && tu > SC_FS) {
328  d *= 1000;
329  tu = (sc_time_unit)(tu - 1);
330  }
331 
332  Tick ticks_per_second =
333  sc_gem5::TimeUnitFrequency[tu] / static_cast<Tick>(d);
334  setClockFrequency(ticks_per_second);
335  specified = true;
336 }
337 
338 sc_time
340 {
341  return sc_time::from_value(1);
342 }
343 
344 const sc_time &
346 {
347  static const sc_time MaxScTime = sc_time::from_value(MaxTick);
348  return MaxScTime;
349 }
350 
351 void
353 {
354  if (d < 0.0)
355  SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive");
356 
357  double dummy;
358  if (modf(log10(d), &dummy) != 0.0) {
360  "value not a power of ten");
361  }
362  if (sc_is_running())
363  SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running");
364 
365  static bool specified = false;
366  if (specified) {
367  SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified");
368  }
369  // This won't detect the timescale being fixed outside of systemc, but
370  // it's at least some protection.
371  if (clockFrequencyFixed()) {
373  "sc_time object(s) constructed");
374  }
375 
376  // Normalize d to seconds.
377  defaultUnit = d * sc_gem5::TimeUnitScale[tu];
378  specified = true;
379 
380  double resolution = SimClock::Float::Hz;
381  if (resolution == 0.0)
382  resolution = sc_gem5::TimeUnitScale[SC_PS];
383  if (defaultUnit < resolution) {
385  "value smaller than time resolution");
386  }
387 }
388 
389 sc_time
391 {
392  return sc_time(defaultUnit, SC_SEC);
393 }
394 
396  _value(), _unit(SC_SEC), _set(true)
397 {
398  if (!t.value())
399  return;
400 
401  Tick frequency = SimClock::Frequency;
402 
403  // Shrink the frequency by scaling down the time period, ie converting
404  // it from cycles per second to cycles per millisecond, etc.
405  while (_unit > 1 && (frequency % 1000 == 0)) {
406  _unit = (sc_time_unit)((int)_unit - 1);
407  frequency /= 1000;
408  }
409 
410  // Convert the frequency into a period.
411  Tick period;
412  if (frequency > 1) {
413  _unit = (sc_time_unit)((int)_unit - 1);
414  period = 1000 / frequency;
415  } else {
416  period = frequency;
417  }
418 
419  // Scale our integer value by the period.
420  _value = t.value() * period;
421 
422  // Shrink the scaled time value by increasing the size of the units
423  // it's measured by, avoiding fractional parts.
424  while (_unit < SC_SEC && (_value % 1000) == 0) {
425  _unit = (sc_time_unit)((int)_unit + 1);
426  _value /= 1000;
427  }
428 }
429 
430 bool
432 {
433  return _set;
434 }
435 
437 
438 const char *
440 {
442 }
443 
444 double sc_time_tuple::to_double() const { return static_cast<double>(_value); }
445 
446 std::string
448 {
449  std::ostringstream ss;
450  ss << _value << ' ' << unit_symbol();
451  return ss.str();
452 }
453 
454 } // namespace sc_core
MipsISA::tu
Bitfield< 30, 28 > tu
Definition: pra_constants.hh:249
sc_core::sc_time::from_value
static sc_time from_value(sc_dt::uint64)
Definition: sc_time.cc:210
SimClock::Float::s
double s
These variables equal the number of ticks in the unit of time they're named after in a double.
Definition: core.cc:49
sc_core::sc_time_tuple::_set
bool _set
Definition: sc_time.hh:135
X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:803
sc_core::sc_time::operator>
bool operator>(const sc_time &) const
Definition: sc_time.cc:164
sc_gem5::TimeUnitScale
double TimeUnitScale[]
Definition: time.cc:53
sc_core::SC_ID_DEFAULT_TIME_UNIT_CHANGED_
const char SC_ID_DEFAULT_TIME_UNIT_CHANGED_[]
Definition: messages.cc:58
ArmISA::t2
Bitfield< 2 > t2
Definition: miscregs_types.hh:228
sc_core::sc_time::from_string
static sc_time from_string(const char *str)
Definition: sc_time.cc:228
sc_core::SC_FS
@ SC_FS
Definition: sc_time.hh:41
setClockFrequency
void setClockFrequency(Tick tps)
Definition: core.cc:112
sc_core::sc_time::operator=
sc_time & operator=(const sc_time &)
Definition: sc_time.cc:108
sc_core::sc_time_tuple::to_string
std::string to_string() const
Definition: sc_time.cc:447
sc_core
Definition: messages.cc:31
sc_core::sc_time_unit
sc_time_unit
Definition: sc_time.hh:40
sc_core::sc_set_default_time_unit
void sc_set_default_time_unit(double d, sc_time_unit tu)
Definition: sc_time.cc:352
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
sc_gem5::TimeUnitFrequency
Tick TimeUnitFrequency[]
Definition: time.cc:62
sc_core::SC_ZERO_TIME
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
sc_core::sc_time::to_double
double to_double() const
Definition: sc_time.cc:121
X86ISA::scale
scale
Definition: types.hh:92
sc_core::sc_time_tuple::unit_symbol
const char * unit_symbol() const
Definition: sc_time.cc:439
sc_core::sc_time::operator==
bool operator==(const sc_time &) const
Definition: sc_time.cc:140
SimClock::Frequency
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:46
sc_core::sc_time::operator+=
sc_time & operator+=(const sc_time &)
Definition: sc_time.cc:176
sc_core::sc_max_time
const sc_time & sc_max_time()
Definition: sc_time.cc:345
time.hh
sc_core::sc_time_tuple::sc_time_tuple
sc_time_tuple()
Definition: sc_time.hh:117
sc_core::sc_time_tuple::to_double
double to_double() const
Definition: sc_time.cc:444
ArmISA::ss
Bitfield< 21 > ss
Definition: miscregs_types.hh:56
ArmISA::a
Bitfield< 8 > a
Definition: miscregs_types.hh:62
SC_REPORT_ERROR
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report_handler.hh:127
sc_dt::uint64
uint64_t uint64
Definition: sc_nbdefs.hh:206
SimClock::Float::Hz
double Hz
These variables the inverse of above.
Definition: core.cc:55
sc_core::sc_time_tuple::value
sc_dt::uint64 value() const
Definition: sc_time.cc:436
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
sc_main.hh
sc_core::sc_time::operator<
bool operator<(const sc_time &) const
Definition: sc_time.cc:152
sc_core::sc_time::to_seconds
double to_seconds() const
Definition: sc_time.cc:126
sc_core::sc_time
Definition: sc_time.hh:49
sc_core::sc_time::value
sc_dt::uint64 value() const
Definition: sc_time.cc:115
sc_core::SC_ID_TIME_CONVERSION_FAILED_
const char SC_ID_TIME_CONVERSION_FAILED_[]
Definition: messages.cc:148
sc_core::operator<<
std::ostream & operator<<(std::ostream &os, sc_status s)
Definition: sc_main.cc:179
clockFrequencyFixed
bool clockFrequencyFixed()
Definition: core.cc:109
sc_core::sc_time::val
uint64_t val
Definition: sc_time.hh:90
sc_core::sc_time_tuple::_value
sc_dt::uint64 _value
Definition: sc_time.hh:133
sc_core::sc_get_default_time_unit
sc_time sc_get_default_time_unit()
Definition: sc_time.cc:390
sc_core::operator-
const sc_time operator-(const sc_time &a, const sc_time &b)
Definition: sc_time.cc:251
sc_core::sc_time::sc_time
sc_time()
Definition: sc_time.cc:64
messages.hh
sc_core::sc_time_tuple::has_value
bool has_value() const
Definition: sc_time.cc:431
sc_core::SC_SEC
@ SC_SEC
Definition: sc_time.hh:46
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
sc_gem5::TimeUnitNames
const char * TimeUnitNames[]
Definition: time.cc:35
core.hh
SC_REPORT_WARNING
#define SC_REPORT_WARNING(msg_type, msg)
Definition: sc_report_handler.hh:123
sc_core::sc_time::operator*=
sc_time & operator*=(double)
Definition: sc_time.cc:190
ArmISA::u
Bitfield< 22 > u
Definition: miscregs_types.hh:348
sc_core::operator/
const sc_time operator/(const sc_time &t, double d)
Definition: sc_time.cc:271
sc_report_handler.hh
sc_core::SC_PS
@ SC_PS
Definition: sc_time.hh:42
sc_core::sc_get_time_resolution
sc_time sc_get_time_resolution()
Definition: sc_time.cc:339
sc_core::sc_set_time_resolution
void sc_set_time_resolution(double d, sc_time_unit tu)
Definition: sc_time.cc:293
ArmISA::b
Bitfield< 7 > b
Definition: miscregs_types.hh:376
sc_gem5::TimeUnitConstantNames
const char * TimeUnitConstantNames[]
Definition: time.cc:44
fixClockFrequency
void fixClockFrequency()
Definition: core.cc:81
sc_core::sc_time::operator/=
sc_time & operator/=(double)
Definition: sc_time.cc:197
types.hh
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
sc_core::sc_time::print
void print(std::ostream &=std::cout) const
Definition: sc_time.cc:204
sc_core::operator*
const sc_time operator*(const sc_time &t, double d)
Definition: sc_time.cc:257
sc_core::operator+
const sc_time operator+(const sc_time &a, const sc_time &b)
Definition: sc_time.cc:245
sc_core::sc_time_tuple
Definition: sc_time.hh:114
sc_core::sc_time::operator>=
bool operator>=(const sc_time &) const
Definition: sc_time.cc:170
ArmISA::t1
Bitfield< 1 > t1
Definition: miscregs_types.hh:229
sc_core::sc_time::operator!=
bool operator!=(const sc_time &) const
Definition: sc_time.cc:146
sc_core::sc_time::operator-=
sc_time & operator-=(const sc_time &)
Definition: sc_time.cc:183
sc_core::sc_time_tuple::_unit
sc_time_unit _unit
Definition: sc_time.hh:134
sc_time.hh
sc_core::SC_ID_SET_DEFAULT_TIME_UNIT_
const char SC_ID_SET_DEFAULT_TIME_UNIT_[]
Definition: messages.cc:57
MaxTick
const Tick MaxTick
Definition: types.hh:65
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
sc_core::SC_ID_SET_TIME_RESOLUTION_
const char SC_ID_SET_TIME_RESOLUTION_[]
Definition: messages.cc:56
sc_core::sc_time::to_string
const std::string to_string() const
Definition: sc_time.cc:132
sc_core::sc_time::operator<=
bool operator<=(const sc_time &) const
Definition: sc_time.cc:158
sc_core::sc_is_running
bool sc_is_running()
Definition: sc_main.cc:142
sc_core::sc_time::from_seconds
static sc_time from_seconds(double)
Definition: sc_time.cc:220

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17