sc_time.cc revision 13124:538eff58fb30
12SN/A/* 22188SN/A * Copyright 2018 Google, Inc. 32SN/A * 42SN/A * Redistribution and use in source and binary forms, with or without 52SN/A * modification, are permitted provided that the following conditions are 62SN/A * met: redistributions of source code must retain the above copyright 72SN/A * notice, this list of conditions and the following disclaimer; 82SN/A * redistributions in binary form must reproduce the above copyright 92SN/A * notice, this list of conditions and the following disclaimer in the 102SN/A * documentation and/or other materials provided with the distribution; 112SN/A * neither the name of the copyright holders nor the names of its 122SN/A * contributors may be used to endorse or promote products derived from 132SN/A * this software without specific prior written permission. 142SN/A * 152SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262SN/A * 272665SN/A * Authors: Gabe Black 282665SN/A */ 292665SN/A 302SN/A#include <vector> 312SN/A 322683Sktlim@umich.edu#include "base/logging.hh" 332683Sktlim@umich.edu#include "base/types.hh" 342SN/A#include "python/pybind11/pybind.hh" 356313Sgblack@eecs.umich.edu#include "systemc/core/python.hh" 362190SN/A#include "systemc/ext/core/sc_time.hh" 373776Sgblack@eecs.umich.edu 384997Sgblack@eecs.umich.edunamespace sc_core 396316Sgblack@eecs.umich.edu{ 406216Snate@binkert.org 411858SN/Anamespace 422680SN/A{ 432683Sktlim@umich.edu 442395SN/Aconst char *TimeUnitNames[] = { 452190SN/A [SC_FS] = "fs", 462188SN/A [SC_PS] = "ps", 47217SN/A [SC_NS] = "ns", 482SN/A [SC_US] = "us", 492SN/A [SC_MS] = "ms", 502SN/A [SC_SEC] = "s" 511858SN/A}; 522SN/A 531070SN/Adouble TimeUnitScale[] = { 541070SN/A [SC_FS] = 1.0e-15, 551917SN/A [SC_PS] = 1.0e-12, 561917SN/A [SC_NS] = 1.0e-9, 572521SN/A [SC_US] = 1.0e-6, 582521SN/A [SC_MS] = 1.0e-3, 592521SN/A [SC_SEC] = 1.0 603548Sgblack@eecs.umich.edu}; 613548Sgblack@eecs.umich.edu 623548Sgblack@eecs.umich.edubool timeFixed = false; 633548Sgblack@eecs.umich.edubool pythonReady = false; 642330SN/A 652330SN/Astruct SetInfo 662SN/A{ 672SN/A SetInfo(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) : 68360SN/A time(time), d(d), tu(tu) 692462SN/A {} 702420SN/A 712SN/A ::sc_core::sc_time *time; 722SN/A double d; 732SN/A ::sc_core::sc_time_unit tu; 742683Sktlim@umich.edu}; 752683Sktlim@umich.edustd::vector<SetInfo> toSet; 762683Sktlim@umich.edu 772683Sktlim@umich.eduvoid 782683Sktlim@umich.edusetWork(sc_time *time, double d, ::sc_core::sc_time_unit tu) 792683Sktlim@umich.edu{ 802683Sktlim@umich.edu //XXX Assuming the time resolution is 1ps. 812683Sktlim@umich.edu double scale = TimeUnitScale[tu] / TimeUnitScale[SC_PS]; 822683Sktlim@umich.edu // Accellera claims there is a linux bug, and that these next two 832683Sktlim@umich.edu // lines work around them. 842683Sktlim@umich.edu volatile double tmp = d * scale + 0.5; 852683Sktlim@umich.edu *time = sc_time::from_value(static_cast<uint64_t>(tmp)); 862683Sktlim@umich.edu} 872683Sktlim@umich.edu 882683Sktlim@umich.eduvoid 892SN/AfixTime() 902683Sktlim@umich.edu{ 912SN/A auto ticks = pybind11::module::import("m5.ticks"); 922107SN/A auto fix_global_frequency = ticks.attr("fixGlobalFrequency"); 932107SN/A fix_global_frequency(); 942107SN/A 952159SN/A for (auto &t: toSet) 962455SN/A setWork(t.time, t.d, t.tu); 972455SN/A toSet.clear(); 982SN/A} 992680SN/A 1002SN/Avoid 1012190SN/Aset(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) 1025543Ssaidi@eecs.umich.edu{ 1036315Sgblack@eecs.umich.edu // Only fix time once. 1046315Sgblack@eecs.umich.edu if (!timeFixed) { 1056315Sgblack@eecs.umich.edu timeFixed = true; 1066315Sgblack@eecs.umich.edu 1076316Sgblack@eecs.umich.edu // If we've run, python is working and we haven't fixed time yet. 1086313Sgblack@eecs.umich.edu if (pythonReady) 1092SN/A fixTime(); 1102190SN/A } 1112683Sktlim@umich.edu if (pythonReady) { 1122SN/A // Time should be working. Set up this sc_time. 1132SN/A setWork(time, d, tu); 1142683Sktlim@umich.edu } else { 1152188SN/A // Time isn't set up yet. Defer setting up this sc_time. 1162378SN/A toSet.emplace_back(time, d, tu); 1172400SN/A } 1186022Sgblack@eecs.umich.edu} 1196022Sgblack@eecs.umich.edu 1202SN/Aclass TimeSetter : public ::sc_gem5::PythonReadyFunc 1212683Sktlim@umich.edu{ 1221858SN/A public: 1232683Sktlim@umich.edu TimeSetter() : ::sc_gem5::PythonReadyFunc() {} 1246022Sgblack@eecs.umich.edu 1252683Sktlim@umich.edu void 1262SN/A run() override 1274997Sgblack@eecs.umich.edu { 1286022Sgblack@eecs.umich.edu // Record that we've run and python/pybind should be usable. 1292SN/A pythonReady = true; 1302862Sktlim@umich.edu 1312864Sktlim@umich.edu // If time is already fixed, let python know. 1322862Sktlim@umich.edu if (timeFixed) 1332683Sktlim@umich.edu fixTime(); 1342SN/A } 1352680SN/A} timeSetter; 136180SN/A 1372SN/Adouble defaultUnit = 1.0e-9; 1382SN/A 1392864Sktlim@umich.edu} // anonymous namespace 1402864Sktlim@umich.edu 1412862Sktlim@umich.edusc_time::sc_time() : val(0) {} 1422862Sktlim@umich.edu 143217SN/Asc_time::sc_time(double d, sc_time_unit tu) 144237SN/A{ 145217SN/A val = 0; 1462683Sktlim@umich.edu if (d != 0) 1472683Sktlim@umich.edu set(this, d, tu); 1485891Sgblack@eecs.umich.edu} 1492683Sktlim@umich.edu 1502190SN/Asc_time::sc_time(const sc_time &t) 1512683Sktlim@umich.edu{ 1522683Sktlim@umich.edu val = t.val; 1532683Sktlim@umich.edu} 1542683Sktlim@umich.edu 1552680SN/Asc_time::sc_time(double d, bool scale) 1562190SN/A{ 1575358Sgblack@eecs.umich.edu //XXX Assuming the time resolution is 1ps. 1585358Sgblack@eecs.umich.edu if (scale) 1595358Sgblack@eecs.umich.edu set(this, d * defaultUnit, SC_SEC); 1605358Sgblack@eecs.umich.edu else 1615358Sgblack@eecs.umich.edu set(this, d, SC_PS); 1625358Sgblack@eecs.umich.edu} 1635358Sgblack@eecs.umich.edu 1645358Sgblack@eecs.umich.edusc_time::sc_time(sc_dt::uint64 v, bool scale) 1655358Sgblack@eecs.umich.edu{ 1665358Sgblack@eecs.umich.edu //XXX Assuming the time resolution is 1ps. 1675358Sgblack@eecs.umich.edu if (scale) 1685358Sgblack@eecs.umich.edu set(this, static_cast<double>(v) * defaultUnit, SC_SEC); 1695358Sgblack@eecs.umich.edu else 1705358Sgblack@eecs.umich.edu set(this, static_cast<double>(v), SC_PS); 1715358Sgblack@eecs.umich.edu} 1725358Sgblack@eecs.umich.edu 1734997Sgblack@eecs.umich.edusc_time & 1746313Sgblack@eecs.umich.edusc_time::operator = (const sc_time &t) 1756313Sgblack@eecs.umich.edu{ 1764997Sgblack@eecs.umich.edu val = t.val; 1772683Sktlim@umich.edu return *this; 1782521SN/A} 1795702Ssaidi@eecs.umich.edu 1805702Ssaidi@eecs.umich.edusc_dt::uint64 1815702Ssaidi@eecs.umich.edusc_time::value() const 1825702Ssaidi@eecs.umich.edu{ 1832683Sktlim@umich.edu return val; 1842SN/A} 1852683Sktlim@umich.edu 1862683Sktlim@umich.edudouble 1872683Sktlim@umich.edusc_time::to_double() const 1882683Sktlim@umich.edu{ 1892683Sktlim@umich.edu return static_cast<double>(val); 1902683Sktlim@umich.edu} 1916022Sgblack@eecs.umich.edudouble 1922683Sktlim@umich.edusc_time::to_seconds() const 1936022Sgblack@eecs.umich.edu{ 1942683Sktlim@umich.edu double d = to_double(); 1954997Sgblack@eecs.umich.edu //XXX Assuming the time resolution is 1ps. 1964997Sgblack@eecs.umich.edu double scale = TimeUnitScale[SC_PS] / TimeUnitScale[SC_SEC]; 1975803Snate@binkert.org return d * scale; 1982683Sktlim@umich.edu} 1992683Sktlim@umich.edu 2005499Ssaidi@eecs.umich.educonst std::string 2015499Ssaidi@eecs.umich.edusc_time::to_string() const 2025499Ssaidi@eecs.umich.edu{ 2035499Ssaidi@eecs.umich.edu warn("%s not implemented.\n", __PRETTY_FUNCTION__); 2045499Ssaidi@eecs.umich.edu return ""; 2052SN/A} 2062SN/A 2072683Sktlim@umich.edubool 2082683Sktlim@umich.edusc_time::operator == (const sc_time &t) const 2092683Sktlim@umich.edu{ 2102683Sktlim@umich.edu return val == t.val; 2112683Sktlim@umich.edu} 2122683Sktlim@umich.edu 2132683Sktlim@umich.edubool 2142683Sktlim@umich.edusc_time::operator != (const sc_time &t) const 2152683Sktlim@umich.edu{ 2162683Sktlim@umich.edu return val != t.val; 2172683Sktlim@umich.edu} 2182683Sktlim@umich.edu 2192683Sktlim@umich.edubool 2202683Sktlim@umich.edusc_time::operator < (const sc_time &t) const 2212SN/A{ 2222SN/A return val < t.val; 2232532SN/A} 224716SN/A 2252378SN/Abool 2262378SN/Asc_time::operator <= (const sc_time &t) const 2272423SN/A{ 228716SN/A return val <= t.val; 229716SN/A} 2302683Sktlim@umich.edu 2312190SN/Abool 2326315Sgblack@eecs.umich.edusc_time::operator > (const sc_time &t) const 2336315Sgblack@eecs.umich.edu{ 2346315Sgblack@eecs.umich.edu return val > t.val; 2356316Sgblack@eecs.umich.edu} 2366315Sgblack@eecs.umich.edu 2376315Sgblack@eecs.umich.edubool 2382190SN/Asc_time::operator >= (const sc_time &t) const 2392SN/A{ 2402SN/A return val >= t.val; 2412SN/A} 2422SN/A 2432SN/Asc_time & 2446313Sgblack@eecs.umich.edusc_time::operator += (const sc_time &t) 2456323Sgblack@eecs.umich.edu{ 2466316Sgblack@eecs.umich.edu val += t.val; 2472SN/A return *this; 2482SN/A} 2492455SN/A 2502SN/Asc_time & 2516313Sgblack@eecs.umich.edusc_time::operator -= (const sc_time &t) 2526323Sgblack@eecs.umich.edu{ 2536315Sgblack@eecs.umich.edu val -= t.val; 2542SN/A return *this; 2552SN/A} 2562455SN/A 2572455SN/Asc_time & 2586313Sgblack@eecs.umich.edusc_time::operator *= (double d) 2596323Sgblack@eecs.umich.edu{ 2606315Sgblack@eecs.umich.edu val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5); 2612SN/A return *this; 2622SN/A} 2632SN/A 2642SN/Asc_time & 2656313Sgblack@eecs.umich.edusc_time::operator /= (double d) 2666323Sgblack@eecs.umich.edu{ 2676316Sgblack@eecs.umich.edu val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5); 2682SN/A return *this; 2692SN/A} 2702455SN/A 2712SN/Avoid 2726313Sgblack@eecs.umich.edusc_time::print(std::ostream &os) const 2736323Sgblack@eecs.umich.edu{ 2746315Sgblack@eecs.umich.edu if (val == 0) { 2752SN/A os << "0 s"; 2762SN/A } else { 2772455SN/A //XXX Assuming the time resolution is 1ps. 2782455SN/A sc_time_unit tu = SC_PS; 2796313Sgblack@eecs.umich.edu uint64_t scaled = val; 2806323Sgblack@eecs.umich.edu while (tu < SC_SEC && (scaled % 1000) == 0) { 2816315Sgblack@eecs.umich.edu tu = (sc_time_unit)((int)tu + 1); 2822SN/A scaled /= 1000; 2832SN/A } 2842SN/A 2852SN/A os << scaled << ' ' << TimeUnitNames[tu]; 2862525SN/A } 2872SN/A} 2882SN/A 2892190SN/Asc_time 2902190SN/Asc_time::from_value(sc_dt::uint64 u) 2912525SN/A{ 2922190SN/A sc_time t; 2932190SN/A t.val = u; 2943276Sgblack@eecs.umich.edu return t; 2953276Sgblack@eecs.umich.edu} 2963276Sgblack@eecs.umich.edu 2973276Sgblack@eecs.umich.edusc_time 2983276Sgblack@eecs.umich.edusc_time::from_seconds(double d) 2993276Sgblack@eecs.umich.edu{ 3003276Sgblack@eecs.umich.edu sc_time t; 3013276Sgblack@eecs.umich.edu set(&t, d, SC_SEC); 3023276Sgblack@eecs.umich.edu return t; 3033276Sgblack@eecs.umich.edu} 3042190SN/A 3052190SN/Asc_time 3062525SN/Asc_time::from_string(const char *str) 3072190SN/A{ 3082190SN/A warn("%s not implemented.\n", __PRETTY_FUNCTION__); 3092SN/A return sc_time(); 3102SN/A} 3112525SN/A 3122SN/Aconst sc_time 3132SN/Aoperator + (const sc_time &a, const sc_time &b) 3143276Sgblack@eecs.umich.edu{ 3153276Sgblack@eecs.umich.edu return sc_time::from_value(a.value() + b.value()); 3163276Sgblack@eecs.umich.edu} 3173276Sgblack@eecs.umich.edu 3183276Sgblack@eecs.umich.educonst sc_time 3193276Sgblack@eecs.umich.eduoperator - (const sc_time &a, const sc_time &b) 3203276Sgblack@eecs.umich.edu{ 3213276Sgblack@eecs.umich.edu return sc_time::from_value(a.value() - b.value()); 3223276Sgblack@eecs.umich.edu} 3233276Sgblack@eecs.umich.edu 3242252SN/Aconst sc_time 3252252SN/Aoperator * (const sc_time &t, double d) 3262525SN/A{ 3272252SN/A volatile double tmp = static_cast<double>(t.value()) * d + 0.5; 3282252SN/A return sc_time::from_value(static_cast<int64_t>(tmp)); 3292251SN/A} 3302251SN/A 3312525SN/Aconst sc_time 3322251SN/Aoperator * (double d, const sc_time &t) 3332251SN/A{ 3346221Snate@binkert.org volatile double tmp = d * static_cast<double>(t.value()) + 0.5; 3356221Snate@binkert.org return sc_time::from_value(static_cast<int64_t>(tmp)); 3364172Ssaidi@eecs.umich.edu} 3376313Sgblack@eecs.umich.edu 3384172Ssaidi@eecs.umich.educonst sc_time 3394172Ssaidi@eecs.umich.eduoperator / (const sc_time &t, double d) 3406221Snate@binkert.org{ 3416221Snate@binkert.org volatile double tmp = static_cast<double>(t.value()) / d + 0.5; 3422SN/A return sc_time::from_value(static_cast<int64_t>(tmp)); 3436313Sgblack@eecs.umich.edu} 3442SN/A 3452SN/Adouble 3466221Snate@binkert.orgoperator / (const sc_time &t1, const sc_time &t2) 3476221Snate@binkert.org{ 3482SN/A return t1.to_double() / t2.to_double(); 3496313Sgblack@eecs.umich.edu} 3502SN/A 3512SN/Astd::ostream & 3526221Snate@binkert.orgoperator << (std::ostream &os, const sc_time &t) 3536221Snate@binkert.org{ 3542SN/A t.print(os); 3556313Sgblack@eecs.umich.edu return os; 3566313Sgblack@eecs.umich.edu} 3576313Sgblack@eecs.umich.edu 3586313Sgblack@eecs.umich.educonst sc_time SC_ZERO_TIME; 3596313Sgblack@eecs.umich.edu 3606313Sgblack@eecs.umich.eduvoid 3616313Sgblack@eecs.umich.edusc_set_time_resolution(double, sc_time_unit) 3626313Sgblack@eecs.umich.edu{ 3636313Sgblack@eecs.umich.edu warn("%s not implemented.\n", __PRETTY_FUNCTION__); 3646313Sgblack@eecs.umich.edu} 3656313Sgblack@eecs.umich.edu 3666313Sgblack@eecs.umich.edusc_time 3676313Sgblack@eecs.umich.edusc_get_time_resolution() 3682SN/A{ 3692SN/A warn("%s not implemented.\n", __PRETTY_FUNCTION__); 3702190SN/A return sc_time(); 3712190SN/A} 3722190SN/A 3732190SN/Aconst sc_time & 3742190SN/Asc_max_time() 3751858SN/A{ 3762561SN/A static const sc_time MaxScTime = sc_time::from_value(MaxTick); 3772SN/A return MaxScTime; 3782680SN/A} 3792SN/A 3802SN/Avoid 3812SN/Asc_set_default_time_unit(double d, sc_time_unit tu) 3822SN/A{ 3832SN/A defaultUnit = d * TimeUnitScale[tu]; 3842SN/A} 3852SN/A 3862683Sktlim@umich.edusc_time 3872SN/Asc_get_default_time_unit() 3882SN/A{ 3892SN/A return sc_time(defaultUnit, SC_SEC); 3902SN/A} 3912190SN/A 392sc_time_tuple::sc_time_tuple(const sc_time &) 393{ 394 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 395} 396 397bool 398sc_time_tuple::has_value() const 399{ 400 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 401 return false; 402} 403 404sc_dt::uint64 405sc_time_tuple::value() const 406{ 407 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 408 return 0; 409} 410 411const char * 412sc_time_tuple::unit_symbol() const 413{ 414 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 415 return ""; 416} 417 418double 419sc_time_tuple::to_double() const 420{ 421 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 422 return 0.0; 423} 424 425std::string 426sc_time_tuple::to_string() const 427{ 428 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 429 return ""; 430} 431 432} // namespace sc_core 433