summaryrefslogtreecommitdiff
path: root/src/systemc/core
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-08-07 03:54:08 -0700
committerGabe Black <gabeblack@google.com>2018-09-20 01:40:30 +0000
commit88be5e34f66acaac13a0bd0f52b55eecb22cde1d (patch)
tree5ad6fea46b469c8042e8e913ab3fd1dae2f62481 /src/systemc/core
parent33e3365bf9876b09362897a3ad9941090e3aca9c (diff)
downloadgem5-88be5e34f66acaac13a0bd0f52b55eecb22cde1d.tar.xz
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 <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core')
-rw-r--r--src/systemc/core/sc_time.cc86
1 files 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 <vector>
+
#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<SetInfo> 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<uint64_t>(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<uint64_t>(tmp);
- }
+ if (d != 0)
+ set(this, d, tu);
}
sc_time::sc_time(const sc_time &t)