sc_time.cc revision 13195
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 3013177Sgabeblack@google.com#include <sstream> 3113039Sgabeblack@google.com#include <vector> 3213039Sgabeblack@google.com 3312837Sgabeblack@google.com#include "base/logging.hh" 3412989Sgabeblack@google.com#include "base/types.hh" 3512986Sgabeblack@google.com#include "python/pybind11/pybind.hh" 3613195Sgabeblack@google.com#include "sim/core.hh" 3713039Sgabeblack@google.com#include "systemc/core/python.hh" 3813149Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 3912837Sgabeblack@google.com#include "systemc/ext/core/sc_time.hh" 4013149Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh" 4112837Sgabeblack@google.com 4212837Sgabeblack@google.comnamespace sc_core 4312837Sgabeblack@google.com{ 4412837Sgabeblack@google.com 4512983Sgabeblack@google.comnamespace 4612837Sgabeblack@google.com{ 4712983Sgabeblack@google.com 4812983Sgabeblack@google.comconst char *TimeUnitNames[] = { 4912983Sgabeblack@google.com [SC_FS] = "fs", 5012983Sgabeblack@google.com [SC_PS] = "ps", 5112983Sgabeblack@google.com [SC_NS] = "ns", 5212983Sgabeblack@google.com [SC_US] = "us", 5312983Sgabeblack@google.com [SC_MS] = "ms", 5412983Sgabeblack@google.com [SC_SEC] = "s" 5512983Sgabeblack@google.com}; 5612983Sgabeblack@google.com 5712983Sgabeblack@google.comdouble TimeUnitScale[] = { 5812983Sgabeblack@google.com [SC_FS] = 1.0e-15, 5912983Sgabeblack@google.com [SC_PS] = 1.0e-12, 6012983Sgabeblack@google.com [SC_NS] = 1.0e-9, 6112983Sgabeblack@google.com [SC_US] = 1.0e-6, 6212983Sgabeblack@google.com [SC_MS] = 1.0e-3, 6312983Sgabeblack@google.com [SC_SEC] = 1.0 6412983Sgabeblack@google.com}; 6512983Sgabeblack@google.com 6613195Sgabeblack@google.comTick TimeUnitFrequency[] = { 6713195Sgabeblack@google.com [SC_FS] = 1ULL * 1000 * 1000 * 1000 * 1000 * 1000, 6813195Sgabeblack@google.com [SC_PS] = 1ULL * 1000 * 1000 * 1000 * 1000, 6913195Sgabeblack@google.com [SC_NS] = 1ULL * 1000 * 1000 * 1000, 7013195Sgabeblack@google.com [SC_US] = 1ULL * 1000 * 1000, 7113195Sgabeblack@google.com [SC_MS] = 1ULL * 1000, 7213195Sgabeblack@google.com [SC_SEC] = 1ULL 7313195Sgabeblack@google.com}; 7413195Sgabeblack@google.com 7513039Sgabeblack@google.combool timeFixed = false; 7613039Sgabeblack@google.combool pythonReady = false; 7713039Sgabeblack@google.com 7813039Sgabeblack@google.comstruct SetInfo 7913039Sgabeblack@google.com{ 8013039Sgabeblack@google.com SetInfo(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) : 8113039Sgabeblack@google.com time(time), d(d), tu(tu) 8213039Sgabeblack@google.com {} 8313039Sgabeblack@google.com 8413039Sgabeblack@google.com ::sc_core::sc_time *time; 8513039Sgabeblack@google.com double d; 8613039Sgabeblack@google.com ::sc_core::sc_time_unit tu; 8713039Sgabeblack@google.com}; 8813039Sgabeblack@google.comstd::vector<SetInfo> toSet; 8913039Sgabeblack@google.com 9012986Sgabeblack@google.comvoid 9113039Sgabeblack@google.comsetWork(sc_time *time, double d, ::sc_core::sc_time_unit tu) 9212986Sgabeblack@google.com{ 9313195Sgabeblack@google.com double scale = TimeUnitScale[tu] * SimClock::Float::s; 9413039Sgabeblack@google.com // Accellera claims there is a linux bug, and that these next two 9513039Sgabeblack@google.com // lines work around them. 9613039Sgabeblack@google.com volatile double tmp = d * scale + 0.5; 9713039Sgabeblack@google.com *time = sc_time::from_value(static_cast<uint64_t>(tmp)); 9813039Sgabeblack@google.com} 9912986Sgabeblack@google.com 10013039Sgabeblack@google.comvoid 10113039Sgabeblack@google.comfixTime() 10213039Sgabeblack@google.com{ 10312986Sgabeblack@google.com auto ticks = pybind11::module::import("m5.ticks"); 10412986Sgabeblack@google.com auto fix_global_frequency = ticks.attr("fixGlobalFrequency"); 10512986Sgabeblack@google.com fix_global_frequency(); 10613039Sgabeblack@google.com 10713039Sgabeblack@google.com for (auto &t: toSet) 10813039Sgabeblack@google.com setWork(t.time, t.d, t.tu); 10913039Sgabeblack@google.com toSet.clear(); 11012986Sgabeblack@google.com} 11112986Sgabeblack@google.com 11213039Sgabeblack@google.comvoid 11313195Sgabeblack@google.comattemptToFixTime() 11413195Sgabeblack@google.com{ 11513195Sgabeblack@google.com // Only fix time once. 11613195Sgabeblack@google.com if (!timeFixed) { 11713195Sgabeblack@google.com timeFixed = true; 11813195Sgabeblack@google.com 11913195Sgabeblack@google.com // If we've run, python is working and we haven't fixed time yet. 12013195Sgabeblack@google.com if (pythonReady) 12113195Sgabeblack@google.com fixTime(); 12213195Sgabeblack@google.com } 12313195Sgabeblack@google.com} 12413195Sgabeblack@google.com 12513195Sgabeblack@google.comvoid 12613149Sgabeblack@google.comsetGlobalFrequency(Tick ticks_per_second) 12713149Sgabeblack@google.com{ 12813149Sgabeblack@google.com auto ticks = pybind11::module::import("m5.ticks"); 12913149Sgabeblack@google.com auto set_global_frequency = ticks.attr("setGlobalFrequency"); 13013149Sgabeblack@google.com set_global_frequency(ticks_per_second); 13113149Sgabeblack@google.com fixTime(); 13213149Sgabeblack@google.com} 13313149Sgabeblack@google.com 13413149Sgabeblack@google.comvoid 13513039Sgabeblack@google.comset(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) 13613039Sgabeblack@google.com{ 13713195Sgabeblack@google.com if (d != 0) 13813195Sgabeblack@google.com attemptToFixTime(); 13913039Sgabeblack@google.com if (pythonReady) { 14013039Sgabeblack@google.com // Time should be working. Set up this sc_time. 14113039Sgabeblack@google.com setWork(time, d, tu); 14213039Sgabeblack@google.com } else { 14313039Sgabeblack@google.com // Time isn't set up yet. Defer setting up this sc_time. 14413039Sgabeblack@google.com toSet.emplace_back(time, d, tu); 14513039Sgabeblack@google.com } 14613039Sgabeblack@google.com} 14713039Sgabeblack@google.com 14813039Sgabeblack@google.comclass TimeSetter : public ::sc_gem5::PythonReadyFunc 14913039Sgabeblack@google.com{ 15013039Sgabeblack@google.com public: 15113039Sgabeblack@google.com TimeSetter() : ::sc_gem5::PythonReadyFunc() {} 15213039Sgabeblack@google.com 15313039Sgabeblack@google.com void 15413039Sgabeblack@google.com run() override 15513039Sgabeblack@google.com { 15613039Sgabeblack@google.com // Record that we've run and python/pybind should be usable. 15713039Sgabeblack@google.com pythonReady = true; 15813039Sgabeblack@google.com 15913039Sgabeblack@google.com // If time is already fixed, let python know. 16013039Sgabeblack@google.com if (timeFixed) 16113039Sgabeblack@google.com fixTime(); 16213039Sgabeblack@google.com } 16313039Sgabeblack@google.com} timeSetter; 16413039Sgabeblack@google.com 16513124Sgabeblack@google.comdouble defaultUnit = 1.0e-9; 16613124Sgabeblack@google.com 16712983Sgabeblack@google.com} // anonymous namespace 16812983Sgabeblack@google.com 16912983Sgabeblack@google.comsc_time::sc_time() : val(0) {} 17012983Sgabeblack@google.com 17112983Sgabeblack@google.comsc_time::sc_time(double d, sc_time_unit tu) 17212983Sgabeblack@google.com{ 17312983Sgabeblack@google.com val = 0; 17413195Sgabeblack@google.com set(this, d, tu); 17512837Sgabeblack@google.com} 17612837Sgabeblack@google.com 17712983Sgabeblack@google.comsc_time::sc_time(const sc_time &t) 17812837Sgabeblack@google.com{ 17912983Sgabeblack@google.com val = t.val; 18012837Sgabeblack@google.com} 18112837Sgabeblack@google.com 18213057Sgabeblack@google.comsc_time::sc_time(double d, bool scale) 18312925Sgabeblack@google.com{ 18413195Sgabeblack@google.com double scaler = scale ? defaultUnit : SimClock::Float::Hz; 18513195Sgabeblack@google.com set(this, d * scaler, SC_SEC); 18612925Sgabeblack@google.com} 18712925Sgabeblack@google.com 18813057Sgabeblack@google.comsc_time::sc_time(sc_dt::uint64 v, bool scale) 18912925Sgabeblack@google.com{ 19013195Sgabeblack@google.com double scaler = scale ? defaultUnit : SimClock::Float::Hz; 19113195Sgabeblack@google.com set(this, static_cast<double>(v) * scaler, SC_SEC); 19212925Sgabeblack@google.com} 19312925Sgabeblack@google.com 19412837Sgabeblack@google.comsc_time & 19512983Sgabeblack@google.comsc_time::operator = (const sc_time &t) 19612837Sgabeblack@google.com{ 19712983Sgabeblack@google.com val = t.val; 19812837Sgabeblack@google.com return *this; 19912837Sgabeblack@google.com} 20012837Sgabeblack@google.com 20112837Sgabeblack@google.comsc_dt::uint64 20212837Sgabeblack@google.comsc_time::value() const 20312837Sgabeblack@google.com{ 20412983Sgabeblack@google.com return val; 20512837Sgabeblack@google.com} 20612837Sgabeblack@google.com 20712837Sgabeblack@google.comdouble 20812837Sgabeblack@google.comsc_time::to_double() const 20912837Sgabeblack@google.com{ 21013040Sgabeblack@google.com return static_cast<double>(val); 21112837Sgabeblack@google.com} 21212837Sgabeblack@google.comdouble 21312837Sgabeblack@google.comsc_time::to_seconds() const 21412837Sgabeblack@google.com{ 21513195Sgabeblack@google.com return to_double() * SimClock::Float::Hz; 21612837Sgabeblack@google.com} 21712837Sgabeblack@google.com 21812837Sgabeblack@google.comconst std::string 21912837Sgabeblack@google.comsc_time::to_string() const 22012837Sgabeblack@google.com{ 22113177Sgabeblack@google.com std::ostringstream ss; 22213177Sgabeblack@google.com print(ss); 22313177Sgabeblack@google.com return ss.str(); 22412837Sgabeblack@google.com} 22512837Sgabeblack@google.com 22612837Sgabeblack@google.combool 22712983Sgabeblack@google.comsc_time::operator == (const sc_time &t) const 22812837Sgabeblack@google.com{ 22912983Sgabeblack@google.com return val == t.val; 23012837Sgabeblack@google.com} 23112837Sgabeblack@google.com 23212837Sgabeblack@google.combool 23312983Sgabeblack@google.comsc_time::operator != (const sc_time &t) const 23412837Sgabeblack@google.com{ 23512983Sgabeblack@google.com return val != t.val; 23612837Sgabeblack@google.com} 23712837Sgabeblack@google.com 23812837Sgabeblack@google.combool 23912983Sgabeblack@google.comsc_time::operator < (const sc_time &t) const 24012837Sgabeblack@google.com{ 24112983Sgabeblack@google.com return val < t.val; 24212837Sgabeblack@google.com} 24312837Sgabeblack@google.com 24412837Sgabeblack@google.combool 24512983Sgabeblack@google.comsc_time::operator <= (const sc_time &t) const 24612837Sgabeblack@google.com{ 24712983Sgabeblack@google.com return val <= t.val; 24812837Sgabeblack@google.com} 24912837Sgabeblack@google.com 25012837Sgabeblack@google.combool 25112983Sgabeblack@google.comsc_time::operator > (const sc_time &t) const 25212837Sgabeblack@google.com{ 25312983Sgabeblack@google.com return val > t.val; 25412837Sgabeblack@google.com} 25512837Sgabeblack@google.com 25612837Sgabeblack@google.combool 25712983Sgabeblack@google.comsc_time::operator >= (const sc_time &t) const 25812837Sgabeblack@google.com{ 25912983Sgabeblack@google.com return val >= t.val; 26012837Sgabeblack@google.com} 26112837Sgabeblack@google.com 26212837Sgabeblack@google.comsc_time & 26312983Sgabeblack@google.comsc_time::operator += (const sc_time &t) 26412837Sgabeblack@google.com{ 26512983Sgabeblack@google.com val += t.val; 26612837Sgabeblack@google.com return *this; 26712837Sgabeblack@google.com} 26812837Sgabeblack@google.com 26912837Sgabeblack@google.comsc_time & 27012983Sgabeblack@google.comsc_time::operator -= (const sc_time &t) 27112837Sgabeblack@google.com{ 27212983Sgabeblack@google.com val -= t.val; 27312837Sgabeblack@google.com return *this; 27412837Sgabeblack@google.com} 27512837Sgabeblack@google.com 27612837Sgabeblack@google.comsc_time & 27713040Sgabeblack@google.comsc_time::operator *= (double d) 27812837Sgabeblack@google.com{ 27913040Sgabeblack@google.com val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5); 28012837Sgabeblack@google.com return *this; 28112837Sgabeblack@google.com} 28212837Sgabeblack@google.com 28312837Sgabeblack@google.comsc_time & 28413040Sgabeblack@google.comsc_time::operator /= (double d) 28512837Sgabeblack@google.com{ 28613040Sgabeblack@google.com val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5); 28712837Sgabeblack@google.com return *this; 28812837Sgabeblack@google.com} 28912837Sgabeblack@google.com 29012837Sgabeblack@google.comvoid 29112983Sgabeblack@google.comsc_time::print(std::ostream &os) const 29212837Sgabeblack@google.com{ 29312983Sgabeblack@google.com if (val == 0) { 29412983Sgabeblack@google.com os << "0 s"; 29512983Sgabeblack@google.com } else { 29613195Sgabeblack@google.com Tick frequency = SimClock::Frequency; 29713195Sgabeblack@google.com 29813195Sgabeblack@google.com // Shrink the frequency by scaling down the time period, ie converting 29913195Sgabeblack@google.com // it from cycles per second to cycles per millisecond, etc. 30013195Sgabeblack@google.com sc_time_unit tu = SC_SEC; 30113195Sgabeblack@google.com while (tu > 1 && (frequency % 1000 == 0)) { 30213195Sgabeblack@google.com tu = (sc_time_unit)((int)tu - 1); 30313195Sgabeblack@google.com frequency /= 1000; 30413195Sgabeblack@google.com } 30513195Sgabeblack@google.com 30613195Sgabeblack@google.com // Convert the frequency into a period. 30713195Sgabeblack@google.com Tick period; 30813195Sgabeblack@google.com if (frequency > 1) { 30913195Sgabeblack@google.com tu = (sc_time_unit)((int)tu - 1); 31013195Sgabeblack@google.com period = 1000 / frequency; 31113195Sgabeblack@google.com } else { 31213195Sgabeblack@google.com period = frequency; 31313195Sgabeblack@google.com } 31413195Sgabeblack@google.com 31513195Sgabeblack@google.com // Scale our integer value by the period. 31613195Sgabeblack@google.com uint64_t scaled = val * period; 31713195Sgabeblack@google.com 31813195Sgabeblack@google.com // Shrink the scaled time value by increasing the size of the units 31913195Sgabeblack@google.com // it's measured by, avoiding fractional parts. 32012983Sgabeblack@google.com while (tu < SC_SEC && (scaled % 1000) == 0) { 32112983Sgabeblack@google.com tu = (sc_time_unit)((int)tu + 1); 32212983Sgabeblack@google.com scaled /= 1000; 32312983Sgabeblack@google.com } 32412983Sgabeblack@google.com 32512983Sgabeblack@google.com os << scaled << ' ' << TimeUnitNames[tu]; 32612983Sgabeblack@google.com } 32712837Sgabeblack@google.com} 32812837Sgabeblack@google.com 32912923Sgabeblack@google.comsc_time 33012983Sgabeblack@google.comsc_time::from_value(sc_dt::uint64 u) 33112923Sgabeblack@google.com{ 33213195Sgabeblack@google.com if (u) 33313195Sgabeblack@google.com attemptToFixTime(); 33412983Sgabeblack@google.com sc_time t; 33512983Sgabeblack@google.com t.val = u; 33612983Sgabeblack@google.com return t; 33712923Sgabeblack@google.com} 33812923Sgabeblack@google.com 33912923Sgabeblack@google.comsc_time 34013057Sgabeblack@google.comsc_time::from_seconds(double d) 34112923Sgabeblack@google.com{ 34213057Sgabeblack@google.com sc_time t; 34313057Sgabeblack@google.com set(&t, d, SC_SEC); 34413057Sgabeblack@google.com return t; 34512923Sgabeblack@google.com} 34612923Sgabeblack@google.com 34712923Sgabeblack@google.comsc_time 34812923Sgabeblack@google.comsc_time::from_string(const char *str) 34912923Sgabeblack@google.com{ 35012923Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 35112923Sgabeblack@google.com return sc_time(); 35212923Sgabeblack@google.com} 35312923Sgabeblack@google.com 35412837Sgabeblack@google.comconst sc_time 35512989Sgabeblack@google.comoperator + (const sc_time &a, const sc_time &b) 35612837Sgabeblack@google.com{ 35712989Sgabeblack@google.com return sc_time::from_value(a.value() + b.value()); 35812837Sgabeblack@google.com} 35912837Sgabeblack@google.com 36012837Sgabeblack@google.comconst sc_time 36112989Sgabeblack@google.comoperator - (const sc_time &a, const sc_time &b) 36212837Sgabeblack@google.com{ 36312989Sgabeblack@google.com return sc_time::from_value(a.value() - b.value()); 36412837Sgabeblack@google.com} 36512837Sgabeblack@google.com 36612837Sgabeblack@google.comconst sc_time 36713040Sgabeblack@google.comoperator * (const sc_time &t, double d) 36812837Sgabeblack@google.com{ 36913040Sgabeblack@google.com volatile double tmp = static_cast<double>(t.value()) * d + 0.5; 37013040Sgabeblack@google.com return sc_time::from_value(static_cast<int64_t>(tmp)); 37112837Sgabeblack@google.com} 37212837Sgabeblack@google.com 37312837Sgabeblack@google.comconst sc_time 37413040Sgabeblack@google.comoperator * (double d, const sc_time &t) 37512837Sgabeblack@google.com{ 37613040Sgabeblack@google.com volatile double tmp = d * static_cast<double>(t.value()) + 0.5; 37713040Sgabeblack@google.com return sc_time::from_value(static_cast<int64_t>(tmp)); 37812837Sgabeblack@google.com} 37912837Sgabeblack@google.com 38012837Sgabeblack@google.comconst sc_time 38113040Sgabeblack@google.comoperator / (const sc_time &t, double d) 38212837Sgabeblack@google.com{ 38313040Sgabeblack@google.com volatile double tmp = static_cast<double>(t.value()) / d + 0.5; 38413040Sgabeblack@google.com return sc_time::from_value(static_cast<int64_t>(tmp)); 38512837Sgabeblack@google.com} 38612837Sgabeblack@google.com 38712837Sgabeblack@google.comdouble 38813040Sgabeblack@google.comoperator / (const sc_time &t1, const sc_time &t2) 38912837Sgabeblack@google.com{ 39013040Sgabeblack@google.com return t1.to_double() / t2.to_double(); 39112837Sgabeblack@google.com} 39212837Sgabeblack@google.com 39312837Sgabeblack@google.comstd::ostream & 39412983Sgabeblack@google.comoperator << (std::ostream &os, const sc_time &t) 39512837Sgabeblack@google.com{ 39612983Sgabeblack@google.com t.print(os); 39712837Sgabeblack@google.com return os; 39812837Sgabeblack@google.com} 39912837Sgabeblack@google.com 40012837Sgabeblack@google.comconst sc_time SC_ZERO_TIME; 40112837Sgabeblack@google.com 40212837Sgabeblack@google.comvoid 40313149Sgabeblack@google.comsc_set_time_resolution(double d, sc_time_unit tu) 40412837Sgabeblack@google.com{ 40513151Sgabeblack@google.com if (d <= 0.0) { 40613149Sgabeblack@google.com SC_REPORT_ERROR("(E514) set time resolution failed", 40713149Sgabeblack@google.com "value not positive"); 40813149Sgabeblack@google.com } 40913149Sgabeblack@google.com double dummy; 41013149Sgabeblack@google.com if (modf(log10(d), &dummy) != 0.0) { 41113149Sgabeblack@google.com SC_REPORT_ERROR("(E514) set time resolution failed", 41213149Sgabeblack@google.com "value not a power of ten"); 41313149Sgabeblack@google.com } 41413149Sgabeblack@google.com if (sc_is_running()) { 41513149Sgabeblack@google.com SC_REPORT_ERROR("(E514) set time resolution failed", 41613149Sgabeblack@google.com "simulation running"); 41713149Sgabeblack@google.com } 41813149Sgabeblack@google.com static bool specified = false; 41913149Sgabeblack@google.com if (specified) { 42013149Sgabeblack@google.com SC_REPORT_ERROR("(E514) set time resolution failed", 42113149Sgabeblack@google.com "already specified"); 42213149Sgabeblack@google.com } 42313149Sgabeblack@google.com // This won't detect the timescale being fixed outside of systemc, but 42413149Sgabeblack@google.com // it's at least some protection. 42513149Sgabeblack@google.com if (timeFixed) { 42613149Sgabeblack@google.com SC_REPORT_ERROR("(E514) set time resolution failed", 42713149Sgabeblack@google.com "sc_time object(s) constructed"); 42813149Sgabeblack@google.com } 42913149Sgabeblack@google.com 43013195Sgabeblack@google.com double seconds = d * TimeUnitScale[tu]; 43113195Sgabeblack@google.com if (seconds < TimeUnitScale[SC_FS]) { 43213149Sgabeblack@google.com SC_REPORT_ERROR("(E514) set time resolution failed", 43313149Sgabeblack@google.com "value smaller than 1 fs"); 43413149Sgabeblack@google.com } 43513195Sgabeblack@google.com 43613195Sgabeblack@google.com if (seconds > defaultUnit) { 43713195Sgabeblack@google.com SC_REPORT_WARNING( 43813195Sgabeblack@google.com "(W516) default time unit changed to time resolution", ""); 43913195Sgabeblack@google.com defaultUnit = seconds; 44013195Sgabeblack@google.com } 44113195Sgabeblack@google.com 44213195Sgabeblack@google.com // Get rid of fractional parts of d. 44313195Sgabeblack@google.com while (d < 1.0 && tu > SC_FS) { 44413195Sgabeblack@google.com d *= 1000; 44513195Sgabeblack@google.com tu = (sc_time_unit)(tu - 1); 44613195Sgabeblack@google.com } 44713195Sgabeblack@google.com 44813195Sgabeblack@google.com Tick ticks_per_second = TimeUnitFrequency[tu] / static_cast<Tick>(d); 44913149Sgabeblack@google.com setGlobalFrequency(ticks_per_second); 45013149Sgabeblack@google.com specified = true; 45112837Sgabeblack@google.com} 45212837Sgabeblack@google.com 45312837Sgabeblack@google.comsc_time 45412837Sgabeblack@google.comsc_get_time_resolution() 45512837Sgabeblack@google.com{ 45613149Sgabeblack@google.com return sc_time::from_value(1); 45712837Sgabeblack@google.com} 45812837Sgabeblack@google.com 45912837Sgabeblack@google.comconst sc_time & 46012837Sgabeblack@google.comsc_max_time() 46112837Sgabeblack@google.com{ 46212989Sgabeblack@google.com static const sc_time MaxScTime = sc_time::from_value(MaxTick); 46312989Sgabeblack@google.com return MaxScTime; 46412837Sgabeblack@google.com} 46512837Sgabeblack@google.com 46612916Sgabeblack@google.comvoid 46713124Sgabeblack@google.comsc_set_default_time_unit(double d, sc_time_unit tu) 46812916Sgabeblack@google.com{ 46913151Sgabeblack@google.com if (d < 0.0) { 47013151Sgabeblack@google.com SC_REPORT_ERROR("(E515) set default time unit failed", 47113151Sgabeblack@google.com "value not positive"); 47213151Sgabeblack@google.com } 47313151Sgabeblack@google.com double dummy; 47413151Sgabeblack@google.com if (modf(log10(d), &dummy) != 0.0) { 47513151Sgabeblack@google.com SC_REPORT_ERROR("(E515) set default time unit failed", 47613151Sgabeblack@google.com "value not a power of ten"); 47713151Sgabeblack@google.com } 47813151Sgabeblack@google.com if (sc_is_running()) { 47913151Sgabeblack@google.com SC_REPORT_ERROR("(E515) set default time unit failed", 48013151Sgabeblack@google.com "simulation running"); 48113151Sgabeblack@google.com } 48213151Sgabeblack@google.com static bool specified = false; 48313151Sgabeblack@google.com if (specified) { 48413151Sgabeblack@google.com SC_REPORT_ERROR("(E515) set default time unit failed", 48513151Sgabeblack@google.com "already specified"); 48613151Sgabeblack@google.com } 48713151Sgabeblack@google.com // This won't detect the timescale being fixed outside of systemc, but 48813151Sgabeblack@google.com // it's at least some protection. 48913151Sgabeblack@google.com if (timeFixed) { 49013151Sgabeblack@google.com SC_REPORT_ERROR("(E515) set default time unit failed", 49113151Sgabeblack@google.com "sc_time object(s) constructed"); 49213151Sgabeblack@google.com } 49313151Sgabeblack@google.com 49413151Sgabeblack@google.com // Normalize d to seconds. 49513124Sgabeblack@google.com defaultUnit = d * TimeUnitScale[tu]; 49613151Sgabeblack@google.com specified = true; 49712916Sgabeblack@google.com} 49812916Sgabeblack@google.com 49912916Sgabeblack@google.comsc_time 50012916Sgabeblack@google.comsc_get_default_time_unit() 50112916Sgabeblack@google.com{ 50213124Sgabeblack@google.com return sc_time(defaultUnit, SC_SEC); 50312916Sgabeblack@google.com} 50412916Sgabeblack@google.com 50512927Sgabeblack@google.comsc_time_tuple::sc_time_tuple(const sc_time &) 50612927Sgabeblack@google.com{ 50712927Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 50812927Sgabeblack@google.com} 50912927Sgabeblack@google.com 51012927Sgabeblack@google.combool 51112927Sgabeblack@google.comsc_time_tuple::has_value() const 51212927Sgabeblack@google.com{ 51312927Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 51412927Sgabeblack@google.com return false; 51512927Sgabeblack@google.com} 51612927Sgabeblack@google.com 51712927Sgabeblack@google.comsc_dt::uint64 51812927Sgabeblack@google.comsc_time_tuple::value() const 51912927Sgabeblack@google.com{ 52012927Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 52112927Sgabeblack@google.com return 0; 52212927Sgabeblack@google.com} 52312927Sgabeblack@google.com 52412927Sgabeblack@google.comconst char * 52512927Sgabeblack@google.comsc_time_tuple::unit_symbol() const 52612927Sgabeblack@google.com{ 52712927Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 52812927Sgabeblack@google.com return ""; 52912927Sgabeblack@google.com} 53012927Sgabeblack@google.com 53112927Sgabeblack@google.comdouble 53212927Sgabeblack@google.comsc_time_tuple::to_double() const 53312927Sgabeblack@google.com{ 53412927Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 53512927Sgabeblack@google.com return 0.0; 53612927Sgabeblack@google.com} 53712927Sgabeblack@google.com 53812927Sgabeblack@google.comstd::string 53912927Sgabeblack@google.comsc_time_tuple::to_string() const 54012927Sgabeblack@google.com{ 54112927Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 54212927Sgabeblack@google.com return ""; 54312927Sgabeblack@google.com} 54412927Sgabeblack@google.com 54512837Sgabeblack@google.com} // namespace sc_core 546