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