112837Sgabeblack@google.com/* 212837Sgabeblack@google.com * Copyright 2018 Google, Inc. 312837Sgabeblack@google.com * 412837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512837Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012837Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312837Sgabeblack@google.com * this software without specific prior written permission. 1412837Sgabeblack@google.com * 1512837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612837Sgabeblack@google.com * 2712837Sgabeblack@google.com * Authors: Gabe Black 2812837Sgabeblack@google.com */ 2912837Sgabeblack@google.com 3013410Sgabeblack@google.com#include <cmath> 3113410Sgabeblack@google.com#include <cstring> 3213177Sgabeblack@google.com#include <sstream> 3313039Sgabeblack@google.com#include <vector> 3413039Sgabeblack@google.com 3512989Sgabeblack@google.com#include "base/types.hh" 3613195Sgabeblack@google.com#include "sim/core.hh" 3713252Sgabeblack@google.com#include "systemc/core/time.hh" 3813317Sgabeblack@google.com#include "systemc/ext/core/messages.hh" 3913149Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 4012837Sgabeblack@google.com#include "systemc/ext/core/sc_time.hh" 4113149Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh" 4212837Sgabeblack@google.com 4312837Sgabeblack@google.comnamespace sc_core 4412837Sgabeblack@google.com{ 4512837Sgabeblack@google.com 4612983Sgabeblack@google.comnamespace 4712837Sgabeblack@google.com{ 4812983Sgabeblack@google.com 4913410Sgabeblack@google.comvoid 5013410Sgabeblack@google.comset(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) 5113410Sgabeblack@google.com{ 5213410Sgabeblack@google.com if (d != 0) 5313410Sgabeblack@google.com fixClockFrequency(); 5413039Sgabeblack@google.com 5513252Sgabeblack@google.com double scale = sc_gem5::TimeUnitScale[tu] * SimClock::Float::s; 5613039Sgabeblack@google.com // Accellera claims there is a linux bug, and that these next two 5713039Sgabeblack@google.com // lines work around them. 5813039Sgabeblack@google.com volatile double tmp = d * scale + 0.5; 5913039Sgabeblack@google.com *time = sc_time::from_value(static_cast<uint64_t>(tmp)); 6013039Sgabeblack@google.com} 6112986Sgabeblack@google.com 6213124Sgabeblack@google.comdouble defaultUnit = 1.0e-9; 6313124Sgabeblack@google.com 6412983Sgabeblack@google.com} // anonymous namespace 6512983Sgabeblack@google.com 6612983Sgabeblack@google.comsc_time::sc_time() : val(0) {} 6712983Sgabeblack@google.com 6812983Sgabeblack@google.comsc_time::sc_time(double d, sc_time_unit tu) 6912983Sgabeblack@google.com{ 7012983Sgabeblack@google.com val = 0; 7113195Sgabeblack@google.com set(this, d, tu); 7212837Sgabeblack@google.com} 7312837Sgabeblack@google.com 7412983Sgabeblack@google.comsc_time::sc_time(const sc_time &t) 7512837Sgabeblack@google.com{ 7612983Sgabeblack@google.com val = t.val; 7712837Sgabeblack@google.com} 7812837Sgabeblack@google.com 7913265Sgabeblack@google.comsc_time::sc_time(double d, const char *unit) 8013265Sgabeblack@google.com{ 8113265Sgabeblack@google.com sc_time_unit tu; 8213265Sgabeblack@google.com for (tu = SC_FS; tu <= SC_SEC; tu = (sc_time_unit)(tu + 1)) { 8313265Sgabeblack@google.com if (strcmp(unit, sc_gem5::TimeUnitNames[tu]) == 0 || 8413265Sgabeblack@google.com strcmp(unit, sc_gem5::TimeUnitConstantNames[tu]) == 0) { 8513265Sgabeblack@google.com break; 8613265Sgabeblack@google.com } 8713265Sgabeblack@google.com } 8813265Sgabeblack@google.com 8913265Sgabeblack@google.com if (tu > SC_SEC) { 9013317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_TIME_CONVERSION_FAILED_,"invalid unit given"); 9113265Sgabeblack@google.com val = 0; 9213265Sgabeblack@google.com return; 9313265Sgabeblack@google.com } 9413265Sgabeblack@google.com set(this, d, tu); 9513265Sgabeblack@google.com} 9613265Sgabeblack@google.com 9713057Sgabeblack@google.comsc_time::sc_time(double d, bool scale) 9812925Sgabeblack@google.com{ 9913195Sgabeblack@google.com double scaler = scale ? defaultUnit : SimClock::Float::Hz; 10013195Sgabeblack@google.com set(this, d * scaler, SC_SEC); 10112925Sgabeblack@google.com} 10212925Sgabeblack@google.com 10313057Sgabeblack@google.comsc_time::sc_time(sc_dt::uint64 v, bool scale) 10412925Sgabeblack@google.com{ 10513195Sgabeblack@google.com double scaler = scale ? defaultUnit : SimClock::Float::Hz; 10613195Sgabeblack@google.com set(this, static_cast<double>(v) * scaler, SC_SEC); 10712925Sgabeblack@google.com} 10812925Sgabeblack@google.com 10912837Sgabeblack@google.comsc_time & 11012983Sgabeblack@google.comsc_time::operator = (const sc_time &t) 11112837Sgabeblack@google.com{ 11212983Sgabeblack@google.com val = t.val; 11312837Sgabeblack@google.com return *this; 11412837Sgabeblack@google.com} 11512837Sgabeblack@google.com 11612837Sgabeblack@google.comsc_dt::uint64 11712837Sgabeblack@google.comsc_time::value() const 11812837Sgabeblack@google.com{ 11912983Sgabeblack@google.com return val; 12012837Sgabeblack@google.com} 12112837Sgabeblack@google.com 12212837Sgabeblack@google.comdouble 12312837Sgabeblack@google.comsc_time::to_double() const 12412837Sgabeblack@google.com{ 12513040Sgabeblack@google.com return static_cast<double>(val); 12612837Sgabeblack@google.com} 12712837Sgabeblack@google.comdouble 12812837Sgabeblack@google.comsc_time::to_seconds() const 12912837Sgabeblack@google.com{ 13013195Sgabeblack@google.com return to_double() * SimClock::Float::Hz; 13112837Sgabeblack@google.com} 13212837Sgabeblack@google.com 13312837Sgabeblack@google.comconst std::string 13412837Sgabeblack@google.comsc_time::to_string() const 13512837Sgabeblack@google.com{ 13613177Sgabeblack@google.com std::ostringstream ss; 13713177Sgabeblack@google.com print(ss); 13813177Sgabeblack@google.com return ss.str(); 13912837Sgabeblack@google.com} 14012837Sgabeblack@google.com 14112837Sgabeblack@google.combool 14212983Sgabeblack@google.comsc_time::operator == (const sc_time &t) const 14312837Sgabeblack@google.com{ 14412983Sgabeblack@google.com return val == t.val; 14512837Sgabeblack@google.com} 14612837Sgabeblack@google.com 14712837Sgabeblack@google.combool 14812983Sgabeblack@google.comsc_time::operator != (const sc_time &t) const 14912837Sgabeblack@google.com{ 15012983Sgabeblack@google.com return val != t.val; 15112837Sgabeblack@google.com} 15212837Sgabeblack@google.com 15312837Sgabeblack@google.combool 15412983Sgabeblack@google.comsc_time::operator < (const sc_time &t) const 15512837Sgabeblack@google.com{ 15612983Sgabeblack@google.com return val < t.val; 15712837Sgabeblack@google.com} 15812837Sgabeblack@google.com 15912837Sgabeblack@google.combool 16012983Sgabeblack@google.comsc_time::operator <= (const sc_time &t) const 16112837Sgabeblack@google.com{ 16212983Sgabeblack@google.com return val <= t.val; 16312837Sgabeblack@google.com} 16412837Sgabeblack@google.com 16512837Sgabeblack@google.combool 16612983Sgabeblack@google.comsc_time::operator > (const sc_time &t) const 16712837Sgabeblack@google.com{ 16812983Sgabeblack@google.com return val > t.val; 16912837Sgabeblack@google.com} 17012837Sgabeblack@google.com 17112837Sgabeblack@google.combool 17212983Sgabeblack@google.comsc_time::operator >= (const sc_time &t) const 17312837Sgabeblack@google.com{ 17412983Sgabeblack@google.com return val >= t.val; 17512837Sgabeblack@google.com} 17612837Sgabeblack@google.com 17712837Sgabeblack@google.comsc_time & 17812983Sgabeblack@google.comsc_time::operator += (const sc_time &t) 17912837Sgabeblack@google.com{ 18012983Sgabeblack@google.com val += t.val; 18112837Sgabeblack@google.com return *this; 18212837Sgabeblack@google.com} 18312837Sgabeblack@google.com 18412837Sgabeblack@google.comsc_time & 18512983Sgabeblack@google.comsc_time::operator -= (const sc_time &t) 18612837Sgabeblack@google.com{ 18712983Sgabeblack@google.com val -= t.val; 18812837Sgabeblack@google.com return *this; 18912837Sgabeblack@google.com} 19012837Sgabeblack@google.com 19112837Sgabeblack@google.comsc_time & 19213040Sgabeblack@google.comsc_time::operator *= (double d) 19312837Sgabeblack@google.com{ 19413040Sgabeblack@google.com val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5); 19512837Sgabeblack@google.com return *this; 19612837Sgabeblack@google.com} 19712837Sgabeblack@google.com 19812837Sgabeblack@google.comsc_time & 19913040Sgabeblack@google.comsc_time::operator /= (double d) 20012837Sgabeblack@google.com{ 20113040Sgabeblack@google.com val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5); 20212837Sgabeblack@google.com return *this; 20312837Sgabeblack@google.com} 20412837Sgabeblack@google.com 20512837Sgabeblack@google.comvoid 20612983Sgabeblack@google.comsc_time::print(std::ostream &os) const 20712837Sgabeblack@google.com{ 20813263Sgabeblack@google.com os << sc_time_tuple(*this).to_string(); 20912837Sgabeblack@google.com} 21012837Sgabeblack@google.com 21112923Sgabeblack@google.comsc_time 21212983Sgabeblack@google.comsc_time::from_value(sc_dt::uint64 u) 21312923Sgabeblack@google.com{ 21413195Sgabeblack@google.com if (u) 21513410Sgabeblack@google.com fixClockFrequency(); 21612983Sgabeblack@google.com sc_time t; 21712983Sgabeblack@google.com t.val = u; 21812983Sgabeblack@google.com return t; 21912923Sgabeblack@google.com} 22012923Sgabeblack@google.com 22112923Sgabeblack@google.comsc_time 22213057Sgabeblack@google.comsc_time::from_seconds(double d) 22312923Sgabeblack@google.com{ 22413057Sgabeblack@google.com sc_time t; 22513057Sgabeblack@google.com set(&t, d, SC_SEC); 22613057Sgabeblack@google.com return t; 22712923Sgabeblack@google.com} 22812923Sgabeblack@google.com 22912923Sgabeblack@google.comsc_time 23012923Sgabeblack@google.comsc_time::from_string(const char *str) 23112923Sgabeblack@google.com{ 23213265Sgabeblack@google.com char *end = nullptr; 23313265Sgabeblack@google.com 23413265Sgabeblack@google.com double d = str ? std::strtod(str, &end) : 0.0; 23513265Sgabeblack@google.com if (str == end || d < 0.0) { 23613317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_TIME_CONVERSION_FAILED_, "invalid value given"); 23713265Sgabeblack@google.com return SC_ZERO_TIME; 23813265Sgabeblack@google.com } 23913265Sgabeblack@google.com 24013265Sgabeblack@google.com while (*end && std::isspace(*end)) 24113265Sgabeblack@google.com end++; 24213265Sgabeblack@google.com 24313265Sgabeblack@google.com return sc_time(d, end); 24412923Sgabeblack@google.com} 24512923Sgabeblack@google.com 24612837Sgabeblack@google.comconst sc_time 24712989Sgabeblack@google.comoperator + (const sc_time &a, const sc_time &b) 24812837Sgabeblack@google.com{ 24912989Sgabeblack@google.com return sc_time::from_value(a.value() + b.value()); 25012837Sgabeblack@google.com} 25112837Sgabeblack@google.com 25212837Sgabeblack@google.comconst sc_time 25312989Sgabeblack@google.comoperator - (const sc_time &a, const sc_time &b) 25412837Sgabeblack@google.com{ 25512989Sgabeblack@google.com return sc_time::from_value(a.value() - b.value()); 25612837Sgabeblack@google.com} 25712837Sgabeblack@google.com 25812837Sgabeblack@google.comconst sc_time 25913040Sgabeblack@google.comoperator * (const sc_time &t, double d) 26012837Sgabeblack@google.com{ 26113040Sgabeblack@google.com volatile double tmp = static_cast<double>(t.value()) * d + 0.5; 26213040Sgabeblack@google.com return sc_time::from_value(static_cast<int64_t>(tmp)); 26312837Sgabeblack@google.com} 26412837Sgabeblack@google.com 26512837Sgabeblack@google.comconst sc_time 26613040Sgabeblack@google.comoperator * (double d, const sc_time &t) 26712837Sgabeblack@google.com{ 26813040Sgabeblack@google.com volatile double tmp = d * static_cast<double>(t.value()) + 0.5; 26913040Sgabeblack@google.com return sc_time::from_value(static_cast<int64_t>(tmp)); 27012837Sgabeblack@google.com} 27112837Sgabeblack@google.com 27212837Sgabeblack@google.comconst sc_time 27313040Sgabeblack@google.comoperator / (const sc_time &t, double d) 27412837Sgabeblack@google.com{ 27513040Sgabeblack@google.com volatile double tmp = static_cast<double>(t.value()) / d + 0.5; 27613040Sgabeblack@google.com return sc_time::from_value(static_cast<int64_t>(tmp)); 27712837Sgabeblack@google.com} 27812837Sgabeblack@google.com 27912837Sgabeblack@google.comdouble 28013040Sgabeblack@google.comoperator / (const sc_time &t1, const sc_time &t2) 28112837Sgabeblack@google.com{ 28213040Sgabeblack@google.com return t1.to_double() / t2.to_double(); 28312837Sgabeblack@google.com} 28412837Sgabeblack@google.com 28512837Sgabeblack@google.comstd::ostream & 28612983Sgabeblack@google.comoperator << (std::ostream &os, const sc_time &t) 28712837Sgabeblack@google.com{ 28812983Sgabeblack@google.com t.print(os); 28912837Sgabeblack@google.com return os; 29012837Sgabeblack@google.com} 29112837Sgabeblack@google.com 29212837Sgabeblack@google.comconst sc_time SC_ZERO_TIME; 29312837Sgabeblack@google.com 29412837Sgabeblack@google.comvoid 29513149Sgabeblack@google.comsc_set_time_resolution(double d, sc_time_unit tu) 29612837Sgabeblack@google.com{ 29713317Sgabeblack@google.com if (d <= 0.0) 29813317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "value not positive"); 29913317Sgabeblack@google.com 30013149Sgabeblack@google.com double dummy; 30113149Sgabeblack@google.com if (modf(log10(d), &dummy) != 0.0) { 30213317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, 30313149Sgabeblack@google.com "value not a power of ten"); 30413149Sgabeblack@google.com } 30513317Sgabeblack@google.com if (sc_is_running()) 30613317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "simulation running"); 30713317Sgabeblack@google.com 30813149Sgabeblack@google.com static bool specified = false; 30913317Sgabeblack@google.com if (specified) 31013317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "already specified"); 31113317Sgabeblack@google.com 31213149Sgabeblack@google.com // This won't detect the timescale being fixed outside of systemc, but 31313149Sgabeblack@google.com // it's at least some protection. 31413410Sgabeblack@google.com if (clockFrequencyFixed()) { 31513317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, 31613149Sgabeblack@google.com "sc_time object(s) constructed"); 31713149Sgabeblack@google.com } 31813149Sgabeblack@google.com 31913252Sgabeblack@google.com double seconds = d * sc_gem5::TimeUnitScale[tu]; 32013317Sgabeblack@google.com if (seconds < sc_gem5::TimeUnitScale[SC_FS]) 32113317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "value smaller than 1 fs"); 32213195Sgabeblack@google.com 32313195Sgabeblack@google.com if (seconds > defaultUnit) { 32413317Sgabeblack@google.com SC_REPORT_WARNING(SC_ID_DEFAULT_TIME_UNIT_CHANGED_, ""); 32513195Sgabeblack@google.com defaultUnit = seconds; 32613195Sgabeblack@google.com } 32713195Sgabeblack@google.com 32813195Sgabeblack@google.com // Get rid of fractional parts of d. 32913195Sgabeblack@google.com while (d < 1.0 && tu > SC_FS) { 33013195Sgabeblack@google.com d *= 1000; 33113195Sgabeblack@google.com tu = (sc_time_unit)(tu - 1); 33213195Sgabeblack@google.com } 33313195Sgabeblack@google.com 33413252Sgabeblack@google.com Tick ticks_per_second = 33513252Sgabeblack@google.com sc_gem5::TimeUnitFrequency[tu] / static_cast<Tick>(d); 33613410Sgabeblack@google.com setClockFrequency(ticks_per_second); 33713149Sgabeblack@google.com specified = true; 33812837Sgabeblack@google.com} 33912837Sgabeblack@google.com 34012837Sgabeblack@google.comsc_time 34112837Sgabeblack@google.comsc_get_time_resolution() 34212837Sgabeblack@google.com{ 34313149Sgabeblack@google.com return sc_time::from_value(1); 34412837Sgabeblack@google.com} 34512837Sgabeblack@google.com 34612837Sgabeblack@google.comconst sc_time & 34712837Sgabeblack@google.comsc_max_time() 34812837Sgabeblack@google.com{ 34912989Sgabeblack@google.com static const sc_time MaxScTime = sc_time::from_value(MaxTick); 35012989Sgabeblack@google.com return MaxScTime; 35112837Sgabeblack@google.com} 35212837Sgabeblack@google.com 35312916Sgabeblack@google.comvoid 35413124Sgabeblack@google.comsc_set_default_time_unit(double d, sc_time_unit tu) 35512916Sgabeblack@google.com{ 35613317Sgabeblack@google.com if (d < 0.0) 35713317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive"); 35813317Sgabeblack@google.com 35913151Sgabeblack@google.com double dummy; 36013151Sgabeblack@google.com if (modf(log10(d), &dummy) != 0.0) { 36113317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, 36213151Sgabeblack@google.com "value not a power of ten"); 36313151Sgabeblack@google.com } 36413317Sgabeblack@google.com if (sc_is_running()) 36513317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running"); 36613317Sgabeblack@google.com 36713151Sgabeblack@google.com static bool specified = false; 36813151Sgabeblack@google.com if (specified) { 36913317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified"); 37013151Sgabeblack@google.com } 37113151Sgabeblack@google.com // This won't detect the timescale being fixed outside of systemc, but 37213151Sgabeblack@google.com // it's at least some protection. 37313410Sgabeblack@google.com if (clockFrequencyFixed()) { 37413317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, 37513151Sgabeblack@google.com "sc_time object(s) constructed"); 37613151Sgabeblack@google.com } 37713151Sgabeblack@google.com 37813151Sgabeblack@google.com // Normalize d to seconds. 37913252Sgabeblack@google.com defaultUnit = d * sc_gem5::TimeUnitScale[tu]; 38013151Sgabeblack@google.com specified = true; 38113247Sgabeblack@google.com 38213247Sgabeblack@google.com double resolution = SimClock::Float::Hz; 38313247Sgabeblack@google.com if (resolution == 0.0) 38413252Sgabeblack@google.com resolution = sc_gem5::TimeUnitScale[SC_PS]; 38513247Sgabeblack@google.com if (defaultUnit < resolution) { 38613317Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, 38713247Sgabeblack@google.com "value smaller than time resolution"); 38813247Sgabeblack@google.com } 38912916Sgabeblack@google.com} 39012916Sgabeblack@google.com 39112916Sgabeblack@google.comsc_time 39212916Sgabeblack@google.comsc_get_default_time_unit() 39312916Sgabeblack@google.com{ 39413124Sgabeblack@google.com return sc_time(defaultUnit, SC_SEC); 39512916Sgabeblack@google.com} 39612916Sgabeblack@google.com 39713263Sgabeblack@google.comsc_time_tuple::sc_time_tuple(const sc_time &t) : 39813263Sgabeblack@google.com _value(), _unit(SC_SEC), _set(true) 39912927Sgabeblack@google.com{ 40013263Sgabeblack@google.com if (!t.value()) 40113263Sgabeblack@google.com return; 40213263Sgabeblack@google.com 40313263Sgabeblack@google.com Tick frequency = SimClock::Frequency; 40413263Sgabeblack@google.com 40513263Sgabeblack@google.com // Shrink the frequency by scaling down the time period, ie converting 40613263Sgabeblack@google.com // it from cycles per second to cycles per millisecond, etc. 40713263Sgabeblack@google.com while (_unit > 1 && (frequency % 1000 == 0)) { 40813263Sgabeblack@google.com _unit = (sc_time_unit)((int)_unit - 1); 40913263Sgabeblack@google.com frequency /= 1000; 41013263Sgabeblack@google.com } 41113263Sgabeblack@google.com 41213263Sgabeblack@google.com // Convert the frequency into a period. 41313263Sgabeblack@google.com Tick period; 41413263Sgabeblack@google.com if (frequency > 1) { 41513263Sgabeblack@google.com _unit = (sc_time_unit)((int)_unit - 1); 41613263Sgabeblack@google.com period = 1000 / frequency; 41713263Sgabeblack@google.com } else { 41813263Sgabeblack@google.com period = frequency; 41913263Sgabeblack@google.com } 42013263Sgabeblack@google.com 42113263Sgabeblack@google.com // Scale our integer value by the period. 42213263Sgabeblack@google.com _value = t.value() * period; 42313263Sgabeblack@google.com 42413263Sgabeblack@google.com // Shrink the scaled time value by increasing the size of the units 42513263Sgabeblack@google.com // it's measured by, avoiding fractional parts. 42613263Sgabeblack@google.com while (_unit < SC_SEC && (_value % 1000) == 0) { 42713263Sgabeblack@google.com _unit = (sc_time_unit)((int)_unit + 1); 42813263Sgabeblack@google.com _value /= 1000; 42913263Sgabeblack@google.com } 43012927Sgabeblack@google.com} 43112927Sgabeblack@google.com 43212927Sgabeblack@google.combool 43312927Sgabeblack@google.comsc_time_tuple::has_value() const 43412927Sgabeblack@google.com{ 43513263Sgabeblack@google.com return _set; 43612927Sgabeblack@google.com} 43712927Sgabeblack@google.com 43813263Sgabeblack@google.comsc_dt::uint64 sc_time_tuple::value() const { return _value; } 43912927Sgabeblack@google.com 44012927Sgabeblack@google.comconst char * 44112927Sgabeblack@google.comsc_time_tuple::unit_symbol() const 44212927Sgabeblack@google.com{ 44313263Sgabeblack@google.com return sc_gem5::TimeUnitNames[_unit]; 44412927Sgabeblack@google.com} 44512927Sgabeblack@google.com 44613263Sgabeblack@google.comdouble sc_time_tuple::to_double() const { return static_cast<double>(_value); } 44712927Sgabeblack@google.com 44812927Sgabeblack@google.comstd::string 44912927Sgabeblack@google.comsc_time_tuple::to_string() const 45012927Sgabeblack@google.com{ 45113263Sgabeblack@google.com std::ostringstream ss; 45213263Sgabeblack@google.com ss << _value << ' ' << unit_symbol(); 45313263Sgabeblack@google.com return ss.str(); 45412927Sgabeblack@google.com} 45512927Sgabeblack@google.com 45612837Sgabeblack@google.com} // namespace sc_core 457