sc_time.cc revision 13039
1955SN/A/*
2955SN/A * Copyright 2018 Google, Inc.
31762SN/A *
4955SN/A * Redistribution and use in source and binary forms, with or without
5955SN/A * modification, are permitted provided that the following conditions are
6955SN/A * met: redistributions of source code must retain the above copyright
7955SN/A * notice, this list of conditions and the following disclaimer;
8955SN/A * redistributions in binary form must reproduce the above copyright
9955SN/A * notice, this list of conditions and the following disclaimer in the
10955SN/A * documentation and/or other materials provided with the distribution;
11955SN/A * neither the name of the copyright holders nor the names of its
12955SN/A * contributors may be used to endorse or promote products derived from
13955SN/A * this software without specific prior written permission.
14955SN/A *
15955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26955SN/A *
27955SN/A * Authors: Gabe Black
282665Ssaidi@eecs.umich.edu */
294762Snate@binkert.org
30955SN/A#include <vector>
315522Snate@binkert.org
324762Snate@binkert.org#include "base/logging.hh"
335522Snate@binkert.org#include "base/types.hh"
34955SN/A#include "python/pybind11/pybind.hh"
355522Snate@binkert.org#include "systemc/core/python.hh"
36955SN/A#include "systemc/ext/core/sc_time.hh"
375522Snate@binkert.org
384202Sbinkertn@umich.edunamespace sc_core
395742Snate@binkert.org{
40955SN/A
414381Sbinkertn@umich.edunamespace
424381Sbinkertn@umich.edu{
43955SN/A
44955SN/Aconst char *TimeUnitNames[] = {
45955SN/A    [SC_FS] = "fs",
464202Sbinkertn@umich.edu    [SC_PS] = "ps",
47955SN/A    [SC_NS] = "ns",
484382Sbinkertn@umich.edu    [SC_US] = "us",
494382Sbinkertn@umich.edu    [SC_MS] = "ms",
504382Sbinkertn@umich.edu    [SC_SEC] = "s"
515517Snate@binkert.org};
525517Snate@binkert.org
534762Snate@binkert.orgdouble TimeUnitScale[] = {
544762Snate@binkert.org    [SC_FS] = 1.0e-15,
554762Snate@binkert.org    [SC_PS] = 1.0e-12,
564762Snate@binkert.org    [SC_NS] = 1.0e-9,
574762Snate@binkert.org    [SC_US] = 1.0e-6,
584762Snate@binkert.org    [SC_MS] = 1.0e-3,
594762Snate@binkert.org    [SC_SEC] = 1.0
604762Snate@binkert.org};
614762Snate@binkert.org
624762Snate@binkert.orgbool timeFixed = false;
635522Snate@binkert.orgbool pythonReady = false;
645604Snate@binkert.org
655604Snate@binkert.orgstruct SetInfo
665604Snate@binkert.org{
674762Snate@binkert.org    SetInfo(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) :
684762Snate@binkert.org        time(time), d(d), tu(tu)
694762Snate@binkert.org    {}
705522Snate@binkert.org
715522Snate@binkert.org    ::sc_core::sc_time *time;
725522Snate@binkert.org    double d;
735522Snate@binkert.org    ::sc_core::sc_time_unit tu;
745604Snate@binkert.org};
755604Snate@binkert.orgstd::vector<SetInfo> toSet;
764762Snate@binkert.org
774762Snate@binkert.orgvoid
784762Snate@binkert.orgsetWork(sc_time *time, double d, ::sc_core::sc_time_unit tu)
794762Snate@binkert.org{
805522Snate@binkert.org    //XXX Assuming the time resolution is 1ps.
814762Snate@binkert.org    double scale = TimeUnitScale[tu] / TimeUnitScale[SC_PS];
824762Snate@binkert.org    // Accellera claims there is a linux bug, and that these next two
835604Snate@binkert.org    // lines work around them.
845604Snate@binkert.org    volatile double tmp = d * scale + 0.5;
855604Snate@binkert.org    *time = sc_time::from_value(static_cast<uint64_t>(tmp));
865604Snate@binkert.org}
875604Snate@binkert.org
885604Snate@binkert.orgvoid
894762Snate@binkert.orgfixTime()
904762Snate@binkert.org{
914762Snate@binkert.org    auto ticks = pybind11::module::import("m5.ticks");
924762Snate@binkert.org    auto fix_global_frequency = ticks.attr("fixGlobalFrequency");
935604Snate@binkert.org    fix_global_frequency();
944762Snate@binkert.org
955522Snate@binkert.org    for (auto &t: toSet)
965522Snate@binkert.org        setWork(t.time, t.d, t.tu);
975522Snate@binkert.org    toSet.clear();
984762Snate@binkert.org}
994382Sbinkertn@umich.edu
1004762Snate@binkert.orgvoid
1014382Sbinkertn@umich.eduset(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu)
1025522Snate@binkert.org{
1034381Sbinkertn@umich.edu    // Only fix time once.
1045522Snate@binkert.org    if (!timeFixed) {
1054762Snate@binkert.org        timeFixed = true;
1064762Snate@binkert.org
1074762Snate@binkert.org        // If we've run, python is working and we haven't fixed time yet.
1085522Snate@binkert.org        if (pythonReady)
1095522Snate@binkert.org            fixTime();
1105522Snate@binkert.org    }
1115522Snate@binkert.org    if (pythonReady) {
1125522Snate@binkert.org        // Time should be working. Set up this sc_time.
1135522Snate@binkert.org        setWork(time, d, tu);
1145522Snate@binkert.org    } else {
1155522Snate@binkert.org        // Time isn't set up yet. Defer setting up this sc_time.
1165522Snate@binkert.org        toSet.emplace_back(time, d, tu);
1174762Snate@binkert.org    }
1184762Snate@binkert.org}
1194762Snate@binkert.org
1204762Snate@binkert.orgclass TimeSetter : public ::sc_gem5::PythonReadyFunc
1214762Snate@binkert.org{
1224762Snate@binkert.org  public:
1234762Snate@binkert.org    TimeSetter() : ::sc_gem5::PythonReadyFunc() {}
1244762Snate@binkert.org
1254762Snate@binkert.org    void
1264762Snate@binkert.org    run() override
1274762Snate@binkert.org    {
1284762Snate@binkert.org        // Record that we've run and python/pybind should be usable.
1294762Snate@binkert.org        pythonReady = true;
1304762Snate@binkert.org
1314762Snate@binkert.org        // If time is already fixed, let python know.
1324762Snate@binkert.org        if (timeFixed)
1334762Snate@binkert.org            fixTime();
1344762Snate@binkert.org    }
1354762Snate@binkert.org} timeSetter;
1364762Snate@binkert.org
1374762Snate@binkert.org} // anonymous namespace
1384762Snate@binkert.org
1394762Snate@binkert.orgsc_time::sc_time() : val(0) {}
1404762Snate@binkert.org
1414762Snate@binkert.orgsc_time::sc_time(double d, sc_time_unit tu)
1424762Snate@binkert.org{
1434762Snate@binkert.org    val = 0;
1444762Snate@binkert.org    if (d != 0)
1454762Snate@binkert.org        set(this, d, tu);
1464762Snate@binkert.org}
1474762Snate@binkert.org
1484762Snate@binkert.orgsc_time::sc_time(const sc_time &t)
1494762Snate@binkert.org{
1504762Snate@binkert.org    val = t.val;
1514762Snate@binkert.org}
152955SN/A
1535584Snate@binkert.orgsc_time::sc_time(double, bool)
1545584Snate@binkert.org{
1555584Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1565584Snate@binkert.org}
1575584Snate@binkert.org
1585584Snate@binkert.orgsc_time::sc_time(sc_dt::uint64, bool)
1595584Snate@binkert.org{
1605584Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1615584Snate@binkert.org}
1625584Snate@binkert.org
1635584Snate@binkert.orgsc_time &
1645584Snate@binkert.orgsc_time::operator = (const sc_time &t)
1655584Snate@binkert.org{
1664382Sbinkertn@umich.edu    val = t.val;
1674202Sbinkertn@umich.edu    return *this;
1685522Snate@binkert.org}
1694382Sbinkertn@umich.edu
1704382Sbinkertn@umich.edusc_dt::uint64
1714382Sbinkertn@umich.edusc_time::value() const
1725584Snate@binkert.org{
1734382Sbinkertn@umich.edu    return val;
1744382Sbinkertn@umich.edu}
1754382Sbinkertn@umich.edu
1765192Ssaidi@eecs.umich.edudouble
1775192Ssaidi@eecs.umich.edusc_time::to_double() const
1785192Ssaidi@eecs.umich.edu{
1795192Ssaidi@eecs.umich.edu    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1805192Ssaidi@eecs.umich.edu    return 0.0;
1815192Ssaidi@eecs.umich.edu}
1825192Ssaidi@eecs.umich.edudouble
1835192Ssaidi@eecs.umich.edusc_time::to_seconds() const
1845192Ssaidi@eecs.umich.edu{
1855192Ssaidi@eecs.umich.edu    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1865192Ssaidi@eecs.umich.edu    return 0.0;
1875192Ssaidi@eecs.umich.edu}
1885192Ssaidi@eecs.umich.edu
1895192Ssaidi@eecs.umich.educonst std::string
1905192Ssaidi@eecs.umich.edusc_time::to_string() const
1915192Ssaidi@eecs.umich.edu{
1925192Ssaidi@eecs.umich.edu    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1935192Ssaidi@eecs.umich.edu    return "";
1945192Ssaidi@eecs.umich.edu}
1955192Ssaidi@eecs.umich.edu
1965192Ssaidi@eecs.umich.edubool
1975192Ssaidi@eecs.umich.edusc_time::operator == (const sc_time &t) const
1985192Ssaidi@eecs.umich.edu{
1995192Ssaidi@eecs.umich.edu    return val == t.val;
2005192Ssaidi@eecs.umich.edu}
2015192Ssaidi@eecs.umich.edu
2025192Ssaidi@eecs.umich.edubool
2035192Ssaidi@eecs.umich.edusc_time::operator != (const sc_time &t) const
2045192Ssaidi@eecs.umich.edu{
2055192Ssaidi@eecs.umich.edu    return val != t.val;
2065192Ssaidi@eecs.umich.edu}
2075192Ssaidi@eecs.umich.edu
2084382Sbinkertn@umich.edubool
2094382Sbinkertn@umich.edusc_time::operator < (const sc_time &t) const
2104382Sbinkertn@umich.edu{
2112667Sstever@eecs.umich.edu    return val < t.val;
2122667Sstever@eecs.umich.edu}
2132667Sstever@eecs.umich.edu
2142667Sstever@eecs.umich.edubool
2152667Sstever@eecs.umich.edusc_time::operator <= (const sc_time &t) const
2162667Sstever@eecs.umich.edu{
2175742Snate@binkert.org    return val <= t.val;
2185742Snate@binkert.org}
2195742Snate@binkert.org
2202037SN/Abool
2212037SN/Asc_time::operator > (const sc_time &t) const
2222037SN/A{
2235793Snate@binkert.org    return val > t.val;
2245793Snate@binkert.org}
2255793Snate@binkert.org
2265793Snate@binkert.orgbool
2275793Snate@binkert.orgsc_time::operator >= (const sc_time &t) const
2284382Sbinkertn@umich.edu{
2294762Snate@binkert.org    return val >= t.val;
2305344Sstever@gmail.com}
2314382Sbinkertn@umich.edu
2325341Sstever@gmail.comsc_time &
2335742Snate@binkert.orgsc_time::operator += (const sc_time &t)
2345742Snate@binkert.org{
2355742Snate@binkert.org    val += t.val;
2365742Snate@binkert.org    return *this;
2375742Snate@binkert.org}
2384762Snate@binkert.org
2395742Snate@binkert.orgsc_time &
2405742Snate@binkert.orgsc_time::operator -= (const sc_time &t)
2415742Snate@binkert.org{
2425742Snate@binkert.org    val -= t.val;
2435742Snate@binkert.org    return *this;
2445742Snate@binkert.org}
2455742Snate@binkert.org
2465341Sstever@gmail.comsc_time &
2475742Snate@binkert.orgsc_time::operator *= (double)
2485341Sstever@gmail.com{
2494773Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2501858SN/A    return *this;
2511858SN/A}
2521085SN/A
2534382Sbinkertn@umich.edusc_time &
2544382Sbinkertn@umich.edusc_time::operator /= (double)
2554762Snate@binkert.org{
2564762Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2574762Snate@binkert.org    return *this;
2585517Snate@binkert.org}
2595517Snate@binkert.org
2605517Snate@binkert.orgvoid
2615517Snate@binkert.orgsc_time::print(std::ostream &os) const
2625517Snate@binkert.org{
2635517Snate@binkert.org    if (val == 0) {
2645517Snate@binkert.org        os << "0 s";
2655517Snate@binkert.org    } else {
2665517Snate@binkert.org        //XXX Assuming the time resolution is 1ps.
2675517Snate@binkert.org        sc_time_unit tu = SC_PS;
2685517Snate@binkert.org        uint64_t scaled = val;
2695517Snate@binkert.org        while (tu < SC_SEC && (scaled % 1000) == 0) {
2705517Snate@binkert.org            tu = (sc_time_unit)((int)tu + 1);
2715517Snate@binkert.org            scaled /= 1000;
2725517Snate@binkert.org        }
2735517Snate@binkert.org
2745517Snate@binkert.org        os << scaled << ' ' << TimeUnitNames[tu];
2755798Snate@binkert.org    }
2765517Snate@binkert.org}
2775517Snate@binkert.org
2785517Snate@binkert.orgsc_time
2795517Snate@binkert.orgsc_time::from_value(sc_dt::uint64 u)
2805517Snate@binkert.org{
2815517Snate@binkert.org    sc_time t;
2825517Snate@binkert.org    t.val = u;
2835517Snate@binkert.org    return t;
2845517Snate@binkert.org}
2855517Snate@binkert.org
2865517Snate@binkert.orgsc_time
2875517Snate@binkert.orgsc_time::from_seconds(double)
2885517Snate@binkert.org{
2895517Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2905517Snate@binkert.org    return sc_time();
2915517Snate@binkert.org}
2925517Snate@binkert.org
2935517Snate@binkert.orgsc_time
2945517Snate@binkert.orgsc_time::from_string(const char *str)
2955517Snate@binkert.org{
2965517Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2975517Snate@binkert.org    return sc_time();
2985517Snate@binkert.org}
2995798Snate@binkert.org
3005798Snate@binkert.orgconst sc_time
3015517Snate@binkert.orgoperator + (const sc_time &a, const sc_time &b)
3025517Snate@binkert.org{
3035517Snate@binkert.org    return sc_time::from_value(a.value() + b.value());
3045517Snate@binkert.org}
3055517Snate@binkert.org
3065517Snate@binkert.orgconst sc_time
3075517Snate@binkert.orgoperator - (const sc_time &a, const sc_time &b)
3085517Snate@binkert.org{
3095517Snate@binkert.org    return sc_time::from_value(a.value() - b.value());
3105517Snate@binkert.org}
3115517Snate@binkert.org
3125517Snate@binkert.orgconst sc_time
3135517Snate@binkert.orgoperator * (const sc_time &, double)
3145522Snate@binkert.org{
3155517Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3165517Snate@binkert.org    return sc_time();
3175517Snate@binkert.org}
3185517Snate@binkert.org
3194762Snate@binkert.orgconst sc_time
3205517Snate@binkert.orgoperator * (double, const sc_time &)
3215517Snate@binkert.org{
3224762Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3235517Snate@binkert.org    return sc_time();
3244762Snate@binkert.org}
3255517Snate@binkert.org
3265517Snate@binkert.orgconst sc_time
3275517Snate@binkert.orgoperator / (const sc_time &, double)
3285517Snate@binkert.org{
3295517Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3305517Snate@binkert.org    return sc_time();
3315517Snate@binkert.org}
3325517Snate@binkert.org
3335517Snate@binkert.orgdouble
3345517Snate@binkert.orgoperator / (const sc_time &, const sc_time &)
3355517Snate@binkert.org{
3365517Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3375517Snate@binkert.org    return 0.0;
3385517Snate@binkert.org}
3395517Snate@binkert.org
3405517Snate@binkert.orgstd::ostream &
3415517Snate@binkert.orgoperator << (std::ostream &os, const sc_time &t)
3425517Snate@binkert.org{
3435517Snate@binkert.org    t.print(os);
3445517Snate@binkert.org    return os;
3455517Snate@binkert.org}
3465517Snate@binkert.org
3475517Snate@binkert.orgconst sc_time SC_ZERO_TIME;
3484762Snate@binkert.org
3494762Snate@binkert.orgvoid
3504762Snate@binkert.orgsc_set_time_resolution(double, sc_time_unit)
3514762Snate@binkert.org{
3524762Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3534762Snate@binkert.org}
3545517Snate@binkert.org
3554762Snate@binkert.orgsc_time
3564762Snate@binkert.orgsc_get_time_resolution()
3574762Snate@binkert.org{
3584762Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3594382Sbinkertn@umich.edu    return sc_time();
3604382Sbinkertn@umich.edu}
3615798Snate@binkert.org
3625798Snate@binkert.orgconst sc_time &
3635798Snate@binkert.orgsc_max_time()
3645798Snate@binkert.org{
3655798Snate@binkert.org    static const sc_time MaxScTime = sc_time::from_value(MaxTick);
3665798Snate@binkert.org    return MaxScTime;
3675798Snate@binkert.org}
3685798Snate@binkert.org
3695798Snate@binkert.orgvoid
3705798Snate@binkert.orgsc_set_default_time_unit(double, sc_time_unit)
3715798Snate@binkert.org{
3725798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3735798Snate@binkert.org}
3745798Snate@binkert.org
3755798Snate@binkert.orgsc_time
3765798Snate@binkert.orgsc_get_default_time_unit()
3775798Snate@binkert.org{
3785798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3795798Snate@binkert.org    return *(sc_time *)nullptr;
3805798Snate@binkert.org}
3815798Snate@binkert.org
3825798Snate@binkert.orgsc_time_tuple::sc_time_tuple(const sc_time &)
3835798Snate@binkert.org{
3845798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3855798Snate@binkert.org}
3865798Snate@binkert.org
3875798Snate@binkert.orgbool
3885798Snate@binkert.orgsc_time_tuple::has_value() const
3895798Snate@binkert.org{
3905798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3915798Snate@binkert.org    return false;
3925517Snate@binkert.org}
3935517Snate@binkert.org
3945517Snate@binkert.orgsc_dt::uint64
3955517Snate@binkert.orgsc_time_tuple::value() const
3965798Snate@binkert.org{
3975798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
3985798Snate@binkert.org    return 0;
3995517Snate@binkert.org}
4005517Snate@binkert.org
4015798Snate@binkert.orgconst char *
4025798Snate@binkert.orgsc_time_tuple::unit_symbol() const
4035798Snate@binkert.org{
4045798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
4055798Snate@binkert.org    return "";
4065517Snate@binkert.org}
4075517Snate@binkert.org
4085517Snate@binkert.orgdouble
4095517Snate@binkert.orgsc_time_tuple::to_double() const
4105517Snate@binkert.org{
4115517Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
4125517Snate@binkert.org    return 0.0;
4135517Snate@binkert.org}
4145798Snate@binkert.org
4155798Snate@binkert.orgstd::string
4165798Snate@binkert.orgsc_time_tuple::to_string() const
4175798Snate@binkert.org{
4185798Snate@binkert.org    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
4195798Snate@binkert.org    return "";
4205517Snate@binkert.org}
4215517Snate@binkert.org
4225517Snate@binkert.org} // namespace sc_core
4235517Snate@binkert.org