From 88be5e34f66acaac13a0bd0f52b55eecb22cde1d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Aug 2018 03:54:08 -0700 Subject: [PATCH] systemc: Use the new python interface to delay fixing the timescale. This is necessary if an sc_time object is constructed globally, either directly or indirectly, before python is available to fix the timescale. The call will be deferred until the interpretter is up and ready. Change-Id: I486c0a90d44a0e0f0ad8c530b7148e1cff04a5cc Reviewed-on: https://gem5-review.googlesource.com/12070 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/sc_time.cc | 86 +++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/src/systemc/core/sc_time.cc b/src/systemc/core/sc_time.cc index 43d39008d..93150aace 100644 --- a/src/systemc/core/sc_time.cc +++ b/src/systemc/core/sc_time.cc @@ -27,9 +27,12 @@ * Authors: Gabe Black */ +#include + #include "base/logging.hh" #include "base/types.hh" #include "python/pybind11/pybind.hh" +#include "systemc/core/python.hh" #include "systemc/ext/core/sc_time.hh" namespace sc_core @@ -56,19 +59,81 @@ double TimeUnitScale[] = { [SC_SEC] = 1.0 }; +bool timeFixed = false; +bool pythonReady = false; + +struct SetInfo +{ + SetInfo(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) : + time(time), d(d), tu(tu) + {} + + ::sc_core::sc_time *time; + double d; + ::sc_core::sc_time_unit tu; +}; +std::vector toSet; + void -fixTimeResolution() +setWork(sc_time *time, double d, ::sc_core::sc_time_unit tu) { - static bool fixed = false; - if (fixed) - return; + //XXX Assuming the time resolution is 1ps. + double scale = TimeUnitScale[tu] / TimeUnitScale[SC_PS]; + // Accellera claims there is a linux bug, and that these next two + // lines work around them. + volatile double tmp = d * scale + 0.5; + *time = sc_time::from_value(static_cast(tmp)); +} +void +fixTime() +{ auto ticks = pybind11::module::import("m5.ticks"); auto fix_global_frequency = ticks.attr("fixGlobalFrequency"); fix_global_frequency(); - fixed = true; + + for (auto &t: toSet) + setWork(t.time, t.d, t.tu); + toSet.clear(); } +void +set(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) +{ + // Only fix time once. + if (!timeFixed) { + timeFixed = true; + + // If we've run, python is working and we haven't fixed time yet. + if (pythonReady) + fixTime(); + } + if (pythonReady) { + // Time should be working. Set up this sc_time. + setWork(time, d, tu); + } else { + // Time isn't set up yet. Defer setting up this sc_time. + toSet.emplace_back(time, d, tu); + } +} + +class TimeSetter : public ::sc_gem5::PythonReadyFunc +{ + public: + TimeSetter() : ::sc_gem5::PythonReadyFunc() {} + + void + run() override + { + // Record that we've run and python/pybind should be usable. + pythonReady = true; + + // If time is already fixed, let python know. + if (timeFixed) + fixTime(); + } +} timeSetter; + } // anonymous namespace sc_time::sc_time() : val(0) {} @@ -76,15 +141,8 @@ sc_time::sc_time() : val(0) {} sc_time::sc_time(double d, sc_time_unit tu) { val = 0; - if (d != 0) { - fixTimeResolution(); - //XXX Assuming the time resolution is 1ps. - double scale = TimeUnitScale[tu] / TimeUnitScale[SC_PS]; - // Accellera claims there is a linux bug, and that these next two - // lines work around them. - volatile double tmp = d * scale + 0.5; - val = static_cast(tmp); - } + if (d != 0) + set(this, d, tu); } sc_time::sc_time(const sc_time &t) -- 2.30.2