gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
41namespace sc_core
42{
43
44namespace
45{
46
47void
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
60double defaultUnit = 1.0e-9;
61
62} // anonymous namespace
63
64sc_time::sc_time() : val(0) {}
65
67{
68 val = 0;
69 set(this, d, tu);
70}
71
73{
74 val = t.val;
75}
76
77sc_time::sc_time(double d, const char *unit)
78{
79 sc_time_unit tu;
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
95sc_time::sc_time(double d, bool scale)
96{
97 double scaler = scale ? defaultUnit : gem5::sim_clock::as_float::Hz;
98 set(this, d * scaler, SC_SEC);
99}
100
102{
103 double scaler = scale ? defaultUnit : gem5::sim_clock::as_float::Hz;
104 set(this, static_cast<double>(v) * scaler, SC_SEC);
105}
106
107sc_time &
109{
110 val = t.val;
111 return *this;
112}
113
116{
117 return val;
118}
119
120double
122{
123 return static_cast<double>(val);
124}
125double
130
131const std::string
133{
134 std::ostringstream ss;
135 print(ss);
136 return ss.str();
137}
138
139bool
141{
142 return val == t.val;
143}
144
145bool
147{
148 return val != t.val;
149}
150
151bool
152sc_time::operator < (const sc_time &t) const
153{
154 return val < t.val;
155}
156
157bool
158sc_time::operator <= (const sc_time &t) const
159{
160 return val <= t.val;
161}
162
163bool
165{
166 return val > t.val;
167}
168
169bool
171{
172 return val >= t.val;
173}
174
175sc_time &
177{
178 val += t.val;
179 return *this;
180}
181
182sc_time &
184{
185 val -= t.val;
186 return *this;
187}
188
189sc_time &
191{
192 val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5);
193 return *this;
194}
195
196sc_time &
198{
199 val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5);
200 return *this;
201}
202
203void
204sc_time::print(std::ostream &os) const
205{
206 os << sc_time_tuple(*this).to_string();
207}
208
211{
212 if (u)
214 sc_time t;
215 t.val = u;
216 return t;
217}
218
221{
222 sc_time t;
223 set(&t, d, SC_SEC);
224 return t;
225}
226
228sc_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
244const sc_time
246{
247 return sc_time::from_value(a.value() + b.value());
248}
249
250const sc_time
252{
253 return sc_time::from_value(a.value() - b.value());
254}
255
256const sc_time
257operator * (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
263const sc_time
264operator * (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
270const sc_time
271operator / (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
277double
278operator / (const sc_time &t1, const sc_time &t2)
279{
280 return t1.to_double() / t2.to_double();
281}
282
283std::ostream &
284operator << (std::ostream &os, const sc_time &t)
285{
286 t.print(os);
287 return os;
288}
289
291
292void
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) {
300 SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_,
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.
313 SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_,
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) {
322 SC_REPORT_WARNING(SC_ID_DEFAULT_TIME_UNIT_CHANGED_, "");
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 gem5::Tick ticks_per_second =
333 sc_gem5::TimeUnitFrequency[tu] / static_cast<gem5::Tick>(d);
334 gem5::setClockFrequency(ticks_per_second);
335 specified = true;
336}
337
338sc_time
343
344const sc_time &
346{
347 static const sc_time MaxScTime = sc_time::from_value(gem5::MaxTick);
348 return MaxScTime;
349}
350
351void
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) {
359 SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_,
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.
372 SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_,
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 = gem5::sim_clock::as_float::Hz;
381 if (resolution == 0.0)
382 resolution = sc_gem5::TimeUnitScale[SC_PS];
383 if (defaultUnit < resolution) {
384 SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_,
385 "value smaller than time resolution");
386 }
387}
388
389sc_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
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 gem5::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
430bool
432{
433 return _set;
434}
435
437
438const char *
443
444double sc_time_tuple::to_double() const { return static_cast<double>(_value); }
445
446std::string
448{
449 std::ostringstream ss;
450 ss << _value << ' ' << unit_symbol();
451 return ss.str();
452}
453
454} // namespace sc_core
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
sc_dt::uint64 value() const
Definition sc_time.cc:436
const char * unit_symbol() const
Definition sc_time.cc:439
sc_time_unit _unit
Definition sc_time.hh:134
std::string to_string() const
Definition sc_time.cc:447
bool has_value() const
Definition sc_time.cc:431
sc_dt::uint64 _value
Definition sc_time.hh:133
double to_double() const
Definition sc_time.cc:444
bool operator!=(const sc_time &) const
Definition sc_time.cc:146
static sc_time from_seconds(double)
Definition sc_time.cc:220
sc_time & operator-=(const sc_time &)
Definition sc_time.cc:183
bool operator>=(const sc_time &) const
Definition sc_time.cc:170
bool operator==(const sc_time &) const
Definition sc_time.cc:140
void print(std::ostream &=std::cout) const
Definition sc_time.cc:204
bool operator>(const sc_time &) const
Definition sc_time.cc:164
static sc_time from_value(sc_dt::uint64)
Definition sc_time.cc:210
static sc_time from_string(const char *str)
Definition sc_time.cc:228
double to_double() const
Definition sc_time.cc:121
sc_time & operator+=(const sc_time &)
Definition sc_time.cc:176
double to_seconds() const
Definition sc_time.cc:126
const std::string to_string() const
Definition sc_time.cc:132
sc_time & operator=(const sc_time &)
Definition sc_time.cc:108
uint64_t val
Definition sc_time.hh:90
sc_time & operator/=(double)
Definition sc_time.cc:197
bool operator<(const sc_time &) const
Definition sc_time.cc:152
bool operator<=(const sc_time &) const
Definition sc_time.cc:158
sc_time & operator*=(double)
Definition sc_time.cc:190
sc_dt::uint64 value() const
Definition sc_time.cc:115
SwitchingFiber b
SwitchingFiber a
Bitfield< 12, 11 > set
Bitfield< 9 > d
Definition misc_types.hh:64
Bitfield< 30, 28 > tu
double Hz
These variables the inverse of above.
Definition core.cc:57
double s
These variables equal the number of ticks in the unit of time they're named after in a double.
Definition core.cc:51
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition core.cc:47
bool clockFrequencyFixed()
Definition core.cc:112
void fixClockFrequency()
Definition core.cc:84
uint64_t Tick
Tick count type.
Definition types.hh:58
const Tick MaxTick
Definition types.hh:60
void setClockFrequency(Tick tps)
Definition core.cc:115
const sc_time operator/(const sc_time &t, double d)
Definition sc_time.cc:271
void sc_set_time_resolution(double d, sc_time_unit tu)
Definition sc_time.cc:293
const sc_time SC_ZERO_TIME
Definition sc_time.cc:290
const sc_time operator+(const sc_time &a, const sc_time &b)
Definition sc_time.cc:245
bool sc_is_running()
Definition sc_main.cc:141
void sc_set_default_time_unit(double d, sc_time_unit tu)
Definition sc_time.cc:352
const sc_time operator*(const sc_time &t, double d)
Definition sc_time.cc:257
sc_time_unit
Definition sc_time.hh:40
@ SC_PS
Definition sc_time.hh:42
@ SC_SEC
Definition sc_time.hh:46
std::ostream & operator<<(std::ostream &os, sc_status s)
Definition sc_main.cc:178
sc_time sc_get_default_time_unit()
Definition sc_time.cc:390
sc_time sc_get_time_resolution()
Definition sc_time.cc:339
const sc_time operator-(const sc_time &a, const sc_time &b)
Definition sc_time.cc:251
const sc_time & sc_max_time()
Definition sc_time.cc:345
uint64_t uint64
Definition sc_nbdefs.hh:172
const char * TimeUnitNames[]
Definition time.cc:35
double TimeUnitScale[]
Definition time.cc:53
gem5::Tick TimeUnitFrequency[]
Definition time.cc:62
const char * TimeUnitConstantNames[]
Definition time.cc:44
#define SC_REPORT_WARNING(msg_type, msg)
#define SC_REPORT_ERROR(msg_type, msg)
std::stringstream ss
Definition trace.test.cc:45

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0