sc_time.cc revision 13252
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"
3813252Sgabeblack@google.com#include "systemc/core/time.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
4913039Sgabeblack@google.combool timeFixed = false;
5013039Sgabeblack@google.combool pythonReady = false;
5113039Sgabeblack@google.com
5213039Sgabeblack@google.comstruct SetInfo
5313039Sgabeblack@google.com{
5413039Sgabeblack@google.com    SetInfo(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) :
5513039Sgabeblack@google.com        time(time), d(d), tu(tu)
5613039Sgabeblack@google.com    {}
5713039Sgabeblack@google.com
5813039Sgabeblack@google.com    ::sc_core::sc_time *time;
5913039Sgabeblack@google.com    double d;
6013039Sgabeblack@google.com    ::sc_core::sc_time_unit tu;
6113039Sgabeblack@google.com};
6213039Sgabeblack@google.comstd::vector<SetInfo> toSet;
6313039Sgabeblack@google.com
6412986Sgabeblack@google.comvoid
6513039Sgabeblack@google.comsetWork(sc_time *time, double d, ::sc_core::sc_time_unit tu)
6612986Sgabeblack@google.com{
6713252Sgabeblack@google.com    double scale = sc_gem5::TimeUnitScale[tu] * SimClock::Float::s;
6813039Sgabeblack@google.com    // Accellera claims there is a linux bug, and that these next two
6913039Sgabeblack@google.com    // lines work around them.
7013039Sgabeblack@google.com    volatile double tmp = d * scale + 0.5;
7113039Sgabeblack@google.com    *time = sc_time::from_value(static_cast<uint64_t>(tmp));
7213039Sgabeblack@google.com}
7312986Sgabeblack@google.com
7413039Sgabeblack@google.comvoid
7513039Sgabeblack@google.comfixTime()
7613039Sgabeblack@google.com{
7712986Sgabeblack@google.com    auto ticks = pybind11::module::import("m5.ticks");
7812986Sgabeblack@google.com    auto fix_global_frequency = ticks.attr("fixGlobalFrequency");
7912986Sgabeblack@google.com    fix_global_frequency();
8013039Sgabeblack@google.com
8113039Sgabeblack@google.com    for (auto &t: toSet)
8213039Sgabeblack@google.com        setWork(t.time, t.d, t.tu);
8313039Sgabeblack@google.com    toSet.clear();
8412986Sgabeblack@google.com}
8512986Sgabeblack@google.com
8613039Sgabeblack@google.comvoid
8713195Sgabeblack@google.comattemptToFixTime()
8813195Sgabeblack@google.com{
8913195Sgabeblack@google.com    // Only fix time once.
9013195Sgabeblack@google.com    if (!timeFixed) {
9113195Sgabeblack@google.com        timeFixed = true;
9213195Sgabeblack@google.com
9313195Sgabeblack@google.com        // If we've run, python is working and we haven't fixed time yet.
9413195Sgabeblack@google.com        if (pythonReady)
9513195Sgabeblack@google.com            fixTime();
9613195Sgabeblack@google.com    }
9713195Sgabeblack@google.com}
9813195Sgabeblack@google.com
9913195Sgabeblack@google.comvoid
10013149Sgabeblack@google.comsetGlobalFrequency(Tick ticks_per_second)
10113149Sgabeblack@google.com{
10213149Sgabeblack@google.com    auto ticks = pybind11::module::import("m5.ticks");
10313149Sgabeblack@google.com    auto set_global_frequency = ticks.attr("setGlobalFrequency");
10413149Sgabeblack@google.com    set_global_frequency(ticks_per_second);
10513149Sgabeblack@google.com    fixTime();
10613149Sgabeblack@google.com}
10713149Sgabeblack@google.com
10813149Sgabeblack@google.comvoid
10913039Sgabeblack@google.comset(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu)
11013039Sgabeblack@google.com{
11113195Sgabeblack@google.com    if (d != 0)
11213195Sgabeblack@google.com        attemptToFixTime();
11313039Sgabeblack@google.com    if (pythonReady) {
11413039Sgabeblack@google.com        // Time should be working. Set up this sc_time.
11513039Sgabeblack@google.com        setWork(time, d, tu);
11613039Sgabeblack@google.com    } else {
11713039Sgabeblack@google.com        // Time isn't set up yet. Defer setting up this sc_time.
11813039Sgabeblack@google.com        toSet.emplace_back(time, d, tu);
11913039Sgabeblack@google.com    }
12013039Sgabeblack@google.com}
12113039Sgabeblack@google.com
12213039Sgabeblack@google.comclass TimeSetter : public ::sc_gem5::PythonReadyFunc
12313039Sgabeblack@google.com{
12413039Sgabeblack@google.com  public:
12513039Sgabeblack@google.com    TimeSetter() : ::sc_gem5::PythonReadyFunc() {}
12613039Sgabeblack@google.com
12713039Sgabeblack@google.com    void
12813039Sgabeblack@google.com    run() override
12913039Sgabeblack@google.com    {
13013039Sgabeblack@google.com        // Record that we've run and python/pybind should be usable.
13113039Sgabeblack@google.com        pythonReady = true;
13213039Sgabeblack@google.com
13313039Sgabeblack@google.com        // If time is already fixed, let python know.
13413039Sgabeblack@google.com        if (timeFixed)
13513039Sgabeblack@google.com            fixTime();
13613039Sgabeblack@google.com    }
13713039Sgabeblack@google.com} timeSetter;
13813039Sgabeblack@google.com
13913124Sgabeblack@google.comdouble defaultUnit = 1.0e-9;
14013124Sgabeblack@google.com
14112983Sgabeblack@google.com} // anonymous namespace
14212983Sgabeblack@google.com
14312983Sgabeblack@google.comsc_time::sc_time() : val(0) {}
14412983Sgabeblack@google.com
14512983Sgabeblack@google.comsc_time::sc_time(double d, sc_time_unit tu)
14612983Sgabeblack@google.com{
14712983Sgabeblack@google.com    val = 0;
14813195Sgabeblack@google.com    set(this, d, tu);
14912837Sgabeblack@google.com}
15012837Sgabeblack@google.com
15112983Sgabeblack@google.comsc_time::sc_time(const sc_time &t)
15212837Sgabeblack@google.com{
15312983Sgabeblack@google.com    val = t.val;
15412837Sgabeblack@google.com}
15512837Sgabeblack@google.com
15613057Sgabeblack@google.comsc_time::sc_time(double d, bool scale)
15712925Sgabeblack@google.com{
15813195Sgabeblack@google.com    double scaler = scale ? defaultUnit : SimClock::Float::Hz;
15913195Sgabeblack@google.com    set(this, d * scaler, SC_SEC);
16012925Sgabeblack@google.com}
16112925Sgabeblack@google.com
16213057Sgabeblack@google.comsc_time::sc_time(sc_dt::uint64 v, bool scale)
16312925Sgabeblack@google.com{
16413195Sgabeblack@google.com    double scaler = scale ? defaultUnit : SimClock::Float::Hz;
16513195Sgabeblack@google.com    set(this, static_cast<double>(v) * scaler, SC_SEC);
16612925Sgabeblack@google.com}
16712925Sgabeblack@google.com
16812837Sgabeblack@google.comsc_time &
16912983Sgabeblack@google.comsc_time::operator = (const sc_time &t)
17012837Sgabeblack@google.com{
17112983Sgabeblack@google.com    val = t.val;
17212837Sgabeblack@google.com    return *this;
17312837Sgabeblack@google.com}
17412837Sgabeblack@google.com
17512837Sgabeblack@google.comsc_dt::uint64
17612837Sgabeblack@google.comsc_time::value() const
17712837Sgabeblack@google.com{
17812983Sgabeblack@google.com    return val;
17912837Sgabeblack@google.com}
18012837Sgabeblack@google.com
18112837Sgabeblack@google.comdouble
18212837Sgabeblack@google.comsc_time::to_double() const
18312837Sgabeblack@google.com{
18413040Sgabeblack@google.com    return static_cast<double>(val);
18512837Sgabeblack@google.com}
18612837Sgabeblack@google.comdouble
18712837Sgabeblack@google.comsc_time::to_seconds() const
18812837Sgabeblack@google.com{
18913195Sgabeblack@google.com    return to_double() * SimClock::Float::Hz;
19012837Sgabeblack@google.com}
19112837Sgabeblack@google.com
19212837Sgabeblack@google.comconst std::string
19312837Sgabeblack@google.comsc_time::to_string() const
19412837Sgabeblack@google.com{
19513177Sgabeblack@google.com    std::ostringstream ss;
19613177Sgabeblack@google.com    print(ss);
19713177Sgabeblack@google.com    return ss.str();
19812837Sgabeblack@google.com}
19912837Sgabeblack@google.com
20012837Sgabeblack@google.combool
20112983Sgabeblack@google.comsc_time::operator == (const sc_time &t) const
20212837Sgabeblack@google.com{
20312983Sgabeblack@google.com    return val == t.val;
20412837Sgabeblack@google.com}
20512837Sgabeblack@google.com
20612837Sgabeblack@google.combool
20712983Sgabeblack@google.comsc_time::operator != (const sc_time &t) const
20812837Sgabeblack@google.com{
20912983Sgabeblack@google.com    return val != t.val;
21012837Sgabeblack@google.com}
21112837Sgabeblack@google.com
21212837Sgabeblack@google.combool
21312983Sgabeblack@google.comsc_time::operator < (const sc_time &t) const
21412837Sgabeblack@google.com{
21512983Sgabeblack@google.com    return val < t.val;
21612837Sgabeblack@google.com}
21712837Sgabeblack@google.com
21812837Sgabeblack@google.combool
21912983Sgabeblack@google.comsc_time::operator <= (const sc_time &t) const
22012837Sgabeblack@google.com{
22112983Sgabeblack@google.com    return val <= t.val;
22212837Sgabeblack@google.com}
22312837Sgabeblack@google.com
22412837Sgabeblack@google.combool
22512983Sgabeblack@google.comsc_time::operator > (const sc_time &t) const
22612837Sgabeblack@google.com{
22712983Sgabeblack@google.com    return val > t.val;
22812837Sgabeblack@google.com}
22912837Sgabeblack@google.com
23012837Sgabeblack@google.combool
23112983Sgabeblack@google.comsc_time::operator >= (const sc_time &t) const
23212837Sgabeblack@google.com{
23312983Sgabeblack@google.com    return val >= t.val;
23412837Sgabeblack@google.com}
23512837Sgabeblack@google.com
23612837Sgabeblack@google.comsc_time &
23712983Sgabeblack@google.comsc_time::operator += (const sc_time &t)
23812837Sgabeblack@google.com{
23912983Sgabeblack@google.com    val += t.val;
24012837Sgabeblack@google.com    return *this;
24112837Sgabeblack@google.com}
24212837Sgabeblack@google.com
24312837Sgabeblack@google.comsc_time &
24412983Sgabeblack@google.comsc_time::operator -= (const sc_time &t)
24512837Sgabeblack@google.com{
24612983Sgabeblack@google.com    val -= t.val;
24712837Sgabeblack@google.com    return *this;
24812837Sgabeblack@google.com}
24912837Sgabeblack@google.com
25012837Sgabeblack@google.comsc_time &
25113040Sgabeblack@google.comsc_time::operator *= (double d)
25212837Sgabeblack@google.com{
25313040Sgabeblack@google.com    val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5);
25412837Sgabeblack@google.com    return *this;
25512837Sgabeblack@google.com}
25612837Sgabeblack@google.com
25712837Sgabeblack@google.comsc_time &
25813040Sgabeblack@google.comsc_time::operator /= (double d)
25912837Sgabeblack@google.com{
26013040Sgabeblack@google.com    val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5);
26112837Sgabeblack@google.com    return *this;
26212837Sgabeblack@google.com}
26312837Sgabeblack@google.com
26412837Sgabeblack@google.comvoid
26512983Sgabeblack@google.comsc_time::print(std::ostream &os) const
26612837Sgabeblack@google.com{
26712983Sgabeblack@google.com    if (val == 0) {
26812983Sgabeblack@google.com        os << "0 s";
26912983Sgabeblack@google.com    } else {
27013195Sgabeblack@google.com        Tick frequency = SimClock::Frequency;
27113195Sgabeblack@google.com
27213195Sgabeblack@google.com        // Shrink the frequency by scaling down the time period, ie converting
27313195Sgabeblack@google.com        // it from cycles per second to cycles per millisecond, etc.
27413195Sgabeblack@google.com        sc_time_unit tu = SC_SEC;
27513195Sgabeblack@google.com        while (tu > 1 && (frequency % 1000 == 0)) {
27613195Sgabeblack@google.com            tu = (sc_time_unit)((int)tu - 1);
27713195Sgabeblack@google.com            frequency /= 1000;
27813195Sgabeblack@google.com        }
27913195Sgabeblack@google.com
28013195Sgabeblack@google.com        // Convert the frequency into a period.
28113195Sgabeblack@google.com        Tick period;
28213195Sgabeblack@google.com        if (frequency > 1) {
28313195Sgabeblack@google.com            tu = (sc_time_unit)((int)tu - 1);
28413195Sgabeblack@google.com            period = 1000 / frequency;
28513195Sgabeblack@google.com        } else {
28613195Sgabeblack@google.com            period = frequency;
28713195Sgabeblack@google.com        }
28813195Sgabeblack@google.com
28913195Sgabeblack@google.com        // Scale our integer value by the period.
29013195Sgabeblack@google.com        uint64_t scaled = val * period;
29113195Sgabeblack@google.com
29213195Sgabeblack@google.com        // Shrink the scaled time value by increasing the size of the units
29313195Sgabeblack@google.com        // it's measured by, avoiding fractional parts.
29412983Sgabeblack@google.com        while (tu < SC_SEC && (scaled % 1000) == 0) {
29512983Sgabeblack@google.com            tu = (sc_time_unit)((int)tu + 1);
29612983Sgabeblack@google.com            scaled /= 1000;
29712983Sgabeblack@google.com        }
29812983Sgabeblack@google.com
29913252Sgabeblack@google.com        os << scaled << ' ' << sc_gem5::TimeUnitNames[tu];
30012983Sgabeblack@google.com    }
30112837Sgabeblack@google.com}
30212837Sgabeblack@google.com
30312923Sgabeblack@google.comsc_time
30412983Sgabeblack@google.comsc_time::from_value(sc_dt::uint64 u)
30512923Sgabeblack@google.com{
30613195Sgabeblack@google.com    if (u)
30713195Sgabeblack@google.com        attemptToFixTime();
30812983Sgabeblack@google.com    sc_time t;
30912983Sgabeblack@google.com    t.val = u;
31012983Sgabeblack@google.com    return t;
31112923Sgabeblack@google.com}
31212923Sgabeblack@google.com
31312923Sgabeblack@google.comsc_time
31413057Sgabeblack@google.comsc_time::from_seconds(double d)
31512923Sgabeblack@google.com{
31613057Sgabeblack@google.com    sc_time t;
31713057Sgabeblack@google.com    set(&t, d, SC_SEC);
31813057Sgabeblack@google.com    return t;
31912923Sgabeblack@google.com}
32012923Sgabeblack@google.com
32112923Sgabeblack@google.comsc_time
32212923Sgabeblack@google.comsc_time::from_string(const char *str)
32312923Sgabeblack@google.com{
32412923Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
32512923Sgabeblack@google.com    return sc_time();
32612923Sgabeblack@google.com}
32712923Sgabeblack@google.com
32812837Sgabeblack@google.comconst sc_time
32912989Sgabeblack@google.comoperator + (const sc_time &a, const sc_time &b)
33012837Sgabeblack@google.com{
33112989Sgabeblack@google.com    return sc_time::from_value(a.value() + b.value());
33212837Sgabeblack@google.com}
33312837Sgabeblack@google.com
33412837Sgabeblack@google.comconst sc_time
33512989Sgabeblack@google.comoperator - (const sc_time &a, const sc_time &b)
33612837Sgabeblack@google.com{
33712989Sgabeblack@google.com    return sc_time::from_value(a.value() - b.value());
33812837Sgabeblack@google.com}
33912837Sgabeblack@google.com
34012837Sgabeblack@google.comconst sc_time
34113040Sgabeblack@google.comoperator * (const sc_time &t, double d)
34212837Sgabeblack@google.com{
34313040Sgabeblack@google.com    volatile double tmp = static_cast<double>(t.value()) * d + 0.5;
34413040Sgabeblack@google.com    return sc_time::from_value(static_cast<int64_t>(tmp));
34512837Sgabeblack@google.com}
34612837Sgabeblack@google.com
34712837Sgabeblack@google.comconst sc_time
34813040Sgabeblack@google.comoperator * (double d, const sc_time &t)
34912837Sgabeblack@google.com{
35013040Sgabeblack@google.com    volatile double tmp = d * static_cast<double>(t.value()) + 0.5;
35113040Sgabeblack@google.com    return sc_time::from_value(static_cast<int64_t>(tmp));
35212837Sgabeblack@google.com}
35312837Sgabeblack@google.com
35412837Sgabeblack@google.comconst sc_time
35513040Sgabeblack@google.comoperator / (const sc_time &t, double d)
35612837Sgabeblack@google.com{
35713040Sgabeblack@google.com    volatile double tmp = static_cast<double>(t.value()) / d + 0.5;
35813040Sgabeblack@google.com    return sc_time::from_value(static_cast<int64_t>(tmp));
35912837Sgabeblack@google.com}
36012837Sgabeblack@google.com
36112837Sgabeblack@google.comdouble
36213040Sgabeblack@google.comoperator / (const sc_time &t1, const sc_time &t2)
36312837Sgabeblack@google.com{
36413040Sgabeblack@google.com    return t1.to_double() / t2.to_double();
36512837Sgabeblack@google.com}
36612837Sgabeblack@google.com
36712837Sgabeblack@google.comstd::ostream &
36812983Sgabeblack@google.comoperator << (std::ostream &os, const sc_time &t)
36912837Sgabeblack@google.com{
37012983Sgabeblack@google.com    t.print(os);
37112837Sgabeblack@google.com    return os;
37212837Sgabeblack@google.com}
37312837Sgabeblack@google.com
37412837Sgabeblack@google.comconst sc_time SC_ZERO_TIME;
37512837Sgabeblack@google.com
37612837Sgabeblack@google.comvoid
37713149Sgabeblack@google.comsc_set_time_resolution(double d, sc_time_unit tu)
37812837Sgabeblack@google.com{
37913151Sgabeblack@google.com    if (d <= 0.0) {
38013149Sgabeblack@google.com        SC_REPORT_ERROR("(E514) set time resolution failed",
38113149Sgabeblack@google.com                "value not positive");
38213149Sgabeblack@google.com    }
38313149Sgabeblack@google.com    double dummy;
38413149Sgabeblack@google.com    if (modf(log10(d), &dummy) != 0.0) {
38513149Sgabeblack@google.com        SC_REPORT_ERROR("(E514) set time resolution failed",
38613149Sgabeblack@google.com                "value not a power of ten");
38713149Sgabeblack@google.com    }
38813149Sgabeblack@google.com    if (sc_is_running()) {
38913149Sgabeblack@google.com        SC_REPORT_ERROR("(E514) set time resolution failed",
39013149Sgabeblack@google.com                "simulation running");
39113149Sgabeblack@google.com    }
39213149Sgabeblack@google.com    static bool specified = false;
39313149Sgabeblack@google.com    if (specified) {
39413149Sgabeblack@google.com        SC_REPORT_ERROR("(E514) set time resolution failed",
39513149Sgabeblack@google.com                "already specified");
39613149Sgabeblack@google.com    }
39713149Sgabeblack@google.com    // This won't detect the timescale being fixed outside of systemc, but
39813149Sgabeblack@google.com    // it's at least some protection.
39913149Sgabeblack@google.com    if (timeFixed) {
40013149Sgabeblack@google.com        SC_REPORT_ERROR("(E514) set time resolution failed",
40113149Sgabeblack@google.com                "sc_time object(s) constructed");
40213149Sgabeblack@google.com    }
40313149Sgabeblack@google.com
40413252Sgabeblack@google.com    double seconds = d * sc_gem5::TimeUnitScale[tu];
40513252Sgabeblack@google.com    if (seconds < sc_gem5::TimeUnitScale[SC_FS]) {
40613149Sgabeblack@google.com        SC_REPORT_ERROR("(E514) set time resolution failed",
40713149Sgabeblack@google.com                "value smaller than 1 fs");
40813149Sgabeblack@google.com    }
40913195Sgabeblack@google.com
41013195Sgabeblack@google.com    if (seconds > defaultUnit) {
41113195Sgabeblack@google.com        SC_REPORT_WARNING(
41213195Sgabeblack@google.com                "(W516) default time unit changed to time resolution", "");
41313195Sgabeblack@google.com        defaultUnit = seconds;
41413195Sgabeblack@google.com    }
41513195Sgabeblack@google.com
41613195Sgabeblack@google.com    // Get rid of fractional parts of d.
41713195Sgabeblack@google.com    while (d < 1.0 && tu > SC_FS) {
41813195Sgabeblack@google.com        d *= 1000;
41913195Sgabeblack@google.com        tu = (sc_time_unit)(tu - 1);
42013195Sgabeblack@google.com    }
42113195Sgabeblack@google.com
42213252Sgabeblack@google.com    Tick ticks_per_second =
42313252Sgabeblack@google.com        sc_gem5::TimeUnitFrequency[tu] / static_cast<Tick>(d);
42413149Sgabeblack@google.com    setGlobalFrequency(ticks_per_second);
42513149Sgabeblack@google.com    specified = true;
42612837Sgabeblack@google.com}
42712837Sgabeblack@google.com
42812837Sgabeblack@google.comsc_time
42912837Sgabeblack@google.comsc_get_time_resolution()
43012837Sgabeblack@google.com{
43113149Sgabeblack@google.com    return sc_time::from_value(1);
43212837Sgabeblack@google.com}
43312837Sgabeblack@google.com
43412837Sgabeblack@google.comconst sc_time &
43512837Sgabeblack@google.comsc_max_time()
43612837Sgabeblack@google.com{
43712989Sgabeblack@google.com    static const sc_time MaxScTime = sc_time::from_value(MaxTick);
43812989Sgabeblack@google.com    return MaxScTime;
43912837Sgabeblack@google.com}
44012837Sgabeblack@google.com
44112916Sgabeblack@google.comvoid
44213124Sgabeblack@google.comsc_set_default_time_unit(double d, sc_time_unit tu)
44312916Sgabeblack@google.com{
44413151Sgabeblack@google.com    if (d < 0.0) {
44513151Sgabeblack@google.com        SC_REPORT_ERROR("(E515) set default time unit failed",
44613151Sgabeblack@google.com                "value not positive");
44713151Sgabeblack@google.com    }
44813151Sgabeblack@google.com    double dummy;
44913151Sgabeblack@google.com    if (modf(log10(d), &dummy) != 0.0) {
45013151Sgabeblack@google.com        SC_REPORT_ERROR("(E515) set default time unit failed",
45113151Sgabeblack@google.com                "value not a power of ten");
45213151Sgabeblack@google.com    }
45313151Sgabeblack@google.com    if (sc_is_running()) {
45413151Sgabeblack@google.com        SC_REPORT_ERROR("(E515) set default time unit failed",
45513151Sgabeblack@google.com                "simulation running");
45613151Sgabeblack@google.com    }
45713151Sgabeblack@google.com    static bool specified = false;
45813151Sgabeblack@google.com    if (specified) {
45913151Sgabeblack@google.com        SC_REPORT_ERROR("(E515) set default time unit failed",
46013151Sgabeblack@google.com                "already specified");
46113151Sgabeblack@google.com    }
46213151Sgabeblack@google.com    // This won't detect the timescale being fixed outside of systemc, but
46313151Sgabeblack@google.com    // it's at least some protection.
46413151Sgabeblack@google.com    if (timeFixed) {
46513151Sgabeblack@google.com        SC_REPORT_ERROR("(E515) set default time unit failed",
46613151Sgabeblack@google.com                "sc_time object(s) constructed");
46713151Sgabeblack@google.com    }
46813151Sgabeblack@google.com
46913151Sgabeblack@google.com    // Normalize d to seconds.
47013252Sgabeblack@google.com    defaultUnit = d * sc_gem5::TimeUnitScale[tu];
47113151Sgabeblack@google.com    specified = true;
47213247Sgabeblack@google.com
47313247Sgabeblack@google.com    double resolution = SimClock::Float::Hz;
47413247Sgabeblack@google.com    if (resolution == 0.0)
47513252Sgabeblack@google.com        resolution = sc_gem5::TimeUnitScale[SC_PS];
47613247Sgabeblack@google.com    if (defaultUnit < resolution) {
47713247Sgabeblack@google.com        SC_REPORT_ERROR("(E515) set default time unit failed",
47813247Sgabeblack@google.com                "value smaller than time resolution");
47913247Sgabeblack@google.com    }
48012916Sgabeblack@google.com}
48112916Sgabeblack@google.com
48212916Sgabeblack@google.comsc_time
48312916Sgabeblack@google.comsc_get_default_time_unit()
48412916Sgabeblack@google.com{
48513124Sgabeblack@google.com    return sc_time(defaultUnit, SC_SEC);
48612916Sgabeblack@google.com}
48712916Sgabeblack@google.com
48812927Sgabeblack@google.comsc_time_tuple::sc_time_tuple(const sc_time &)
48912927Sgabeblack@google.com{
49012927Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
49112927Sgabeblack@google.com}
49212927Sgabeblack@google.com
49312927Sgabeblack@google.combool
49412927Sgabeblack@google.comsc_time_tuple::has_value() const
49512927Sgabeblack@google.com{
49612927Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
49712927Sgabeblack@google.com    return false;
49812927Sgabeblack@google.com}
49912927Sgabeblack@google.com
50012927Sgabeblack@google.comsc_dt::uint64
50112927Sgabeblack@google.comsc_time_tuple::value() const
50212927Sgabeblack@google.com{
50312927Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
50412927Sgabeblack@google.com    return 0;
50512927Sgabeblack@google.com}
50612927Sgabeblack@google.com
50712927Sgabeblack@google.comconst char *
50812927Sgabeblack@google.comsc_time_tuple::unit_symbol() const
50912927Sgabeblack@google.com{
51012927Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
51112927Sgabeblack@google.com    return "";
51212927Sgabeblack@google.com}
51312927Sgabeblack@google.com
51412927Sgabeblack@google.comdouble
51512927Sgabeblack@google.comsc_time_tuple::to_double() const
51612927Sgabeblack@google.com{
51712927Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
51812927Sgabeblack@google.com    return 0.0;
51912927Sgabeblack@google.com}
52012927Sgabeblack@google.com
52112927Sgabeblack@google.comstd::string
52212927Sgabeblack@google.comsc_time_tuple::to_string() const
52312927Sgabeblack@google.com{
52412927Sgabeblack@google.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
52512927Sgabeblack@google.com    return "";
52612927Sgabeblack@google.com}
52712927Sgabeblack@google.com
52812837Sgabeblack@google.com} // namespace sc_core
529