systemc: Implement sc_(g|s)et_time_resolution.
authorGabe Black <gabeblack@google.com>
Sun, 2 Sep 2018 00:15:24 +0000 (17:15 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 3 Oct 2018 00:45:39 +0000 (00:45 +0000)
Change-Id: If546bea633e777cdb2b14f47c0d9d50b044b99cf
Reviewed-on: https://gem5-review.googlesource.com/c/12461
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/core/sc_time.cc

index 96877e89ef9cdad159da8351f09109e8a3fba5a7..e0e8cf107e3b4bfa187d70a5b066b93c2eb306ff 100644 (file)
@@ -33,7 +33,9 @@
 #include "base/types.hh"
 #include "python/pybind11/pybind.hh"
 #include "systemc/core/python.hh"
+#include "systemc/ext/core/sc_main.hh"
 #include "systemc/ext/core/sc_time.hh"
+#include "systemc/ext/utils/sc_report_handler.hh"
 
 namespace sc_core
 {
@@ -97,6 +99,15 @@ fixTime()
     toSet.clear();
 }
 
+void
+setGlobalFrequency(Tick ticks_per_second)
+{
+    auto ticks = pybind11::module::import("m5.ticks");
+    auto set_global_frequency = ticks.attr("setGlobalFrequency");
+    set_global_frequency(ticks_per_second);
+    fixTime();
+}
+
 void
 set(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu)
 {
@@ -358,16 +369,51 @@ operator << (std::ostream &os, const sc_time &t)
 const sc_time SC_ZERO_TIME;
 
 void
-sc_set_time_resolution(double, sc_time_unit)
+sc_set_time_resolution(double d, sc_time_unit tu)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    if (d < 0.0) {
+        SC_REPORT_ERROR("(E514) set time resolution failed",
+                "value not positive");
+    }
+    double dummy;
+    if (modf(log10(d), &dummy) != 0.0) {
+        SC_REPORT_ERROR("(E514) set time resolution failed",
+                "value not a power of ten");
+    }
+    if (sc_is_running()) {
+        SC_REPORT_ERROR("(E514) set time resolution failed",
+                "simulation running");
+    }
+    static bool specified = false;
+    if (specified) {
+        SC_REPORT_ERROR("(E514) set time resolution failed",
+                "already specified");
+    }
+    // This won't detect the timescale being fixed outside of systemc, but
+    // it's at least some protection.
+    if (timeFixed) {
+        SC_REPORT_ERROR("(E514) set time resolution failed",
+                "sc_time object(s) constructed");
+    }
+
+    // Normalize d to seconds.
+    d *= TimeUnitScale[tu];
+    if (d < TimeUnitScale[SC_FS]) {
+        SC_REPORT_ERROR("(E514) set time resolution failed",
+                "value smaller than 1 fs");
+    }
+    // Change d from a period to a frequency.
+    d = 1 / d;
+    // Convert to integer ticks.
+    Tick ticks_per_second = static_cast<Tick>(d);
+    setGlobalFrequency(ticks_per_second);
+    specified = true;
 }
 
 sc_time
 sc_get_time_resolution()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return sc_time();
+    return sc_time::from_value(1);
 }
 
 const sc_time &