systemc: Implement some of the basics of sc_time.
authorGabe Black <gabeblack@google.com>
Thu, 19 Jul 2018 23:53:27 +0000 (16:53 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 11 Sep 2018 21:41:09 +0000 (21:41 +0000)
This is a very incomplete implementation, but is enough to unblock
implementing some other dependent features.

Change-Id: Ibd2f3476fe01389e277c6956d48337f551d14acd
Reviewed-on: https://gem5-review.googlesource.com/12034
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/core/sc_time.cc
src/systemc/ext/core/sc_time.hh

index 167b37494ec398f51a42bf43bc533279cb031e67..002121e88f6d0ee618d6a2bcf860bb0f47b757ca 100644 (file)
 namespace sc_core
 {
 
-sc_time::sc_time()
+namespace
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
 
-sc_time::sc_time(double, sc_time_unit)
+const char *TimeUnitNames[] = {
+    [SC_FS] = "fs",
+    [SC_PS] = "ps",
+    [SC_NS] = "ns",
+    [SC_US] = "us",
+    [SC_MS] = "ms",
+    [SC_SEC] = "s"
+};
+
+double TimeUnitScale[] = {
+    [SC_FS] = 1.0e-15,
+    [SC_PS] = 1.0e-12,
+    [SC_NS] = 1.0e-9,
+    [SC_US] = 1.0e-6,
+    [SC_MS] = 1.0e-3,
+    [SC_SEC] = 1.0
+};
+
+} // anonymous namespace
+
+sc_time::sc_time() : val(0) {}
+
+sc_time::sc_time(double d, sc_time_unit tu)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    val = 0;
+    if (d != 0) {
+        //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);
+    }
 }
 
-sc_time::sc_time(const sc_time &)
+sc_time::sc_time(const sc_time &t)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    val = t.val;
 }
 
 sc_time::sc_time(double, bool)
@@ -59,17 +87,16 @@ sc_time::sc_time(sc_dt::uint64, bool)
 }
 
 sc_time &
-sc_time::operator = (const sc_time &)
+sc_time::operator = (const sc_time &t)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    val = t.val;
     return *this;
 }
 
 sc_dt::uint64
 sc_time::value() const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return 0;
+    return val;
 }
 
 double
@@ -93,58 +120,52 @@ sc_time::to_string() const
 }
 
 bool
-sc_time::operator == (const sc_time &) const
+sc_time::operator == (const sc_time &t) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return true;
+    return val == t.val;
 }
 
 bool
-sc_time::operator != (const sc_time &) const
+sc_time::operator != (const sc_time &t) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return false;
+    return val != t.val;
 }
 
 bool
-sc_time::operator < (const sc_time &) const
+sc_time::operator < (const sc_time &t) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return false;
+    return val < t.val;
 }
 
 bool
-sc_time::operator <= (const sc_time &) const
+sc_time::operator <= (const sc_time &t) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return true;
+    return val <= t.val;
 }
 
 bool
-sc_time::operator > (const sc_time &) const
+sc_time::operator > (const sc_time &t) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return false;
+    return val > t.val;
 }
 
 bool
-sc_time::operator >= (const sc_time &) const
+sc_time::operator >= (const sc_time &t) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return true;
+    return val >= t.val;
 }
 
 sc_time &
-sc_time::operator += (const sc_time &)
+sc_time::operator += (const sc_time &t)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    val += t.val;
     return *this;
 }
 
 sc_time &
-sc_time::operator -= (const sc_time &)
+sc_time::operator -= (const sc_time &t)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    val -= t.val;
     return *this;
 }
 
@@ -163,16 +184,29 @@ sc_time::operator /= (double)
 }
 
 void
-sc_time::print(std::ostream &) const
+sc_time::print(std::ostream &os) const
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    if (val == 0) {
+        os << "0 s";
+    } else {
+        //XXX Assuming the time resolution is 1ps.
+        sc_time_unit tu = SC_PS;
+        uint64_t scaled = val;
+        while (tu < SC_SEC && (scaled % 1000) == 0) {
+            tu = (sc_time_unit)((int)tu + 1);
+            scaled /= 1000;
+        }
+
+        os << scaled << ' ' << TimeUnitNames[tu];
+    }
 }
 
 sc_time
-sc_time::from_value(sc_dt::uint64)
+sc_time::from_value(sc_dt::uint64 u)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return sc_time();
+    sc_time t;
+    t.val = u;
+    return t;
 }
 
 sc_time
@@ -232,9 +266,9 @@ operator / (const sc_time &, const sc_time &)
 }
 
 std::ostream &
-operator << (std::ostream &os, const sc_time &)
+operator << (std::ostream &os, const sc_time &t)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    t.print(os);
     return os;
 }
 
index 362834cce7333e2f8f8376662a91cb495b6b8226..0147555227f51cffc1a0dee10e4ab2252269157e 100644 (file)
@@ -84,6 +84,9 @@ class sc_time
     static sc_time from_value(sc_dt::uint64);
     static sc_time from_seconds(double);
     static sc_time from_string(const char *str);
+
+  private:
+    uint64_t val;
 };
 
 const sc_time operator + (const sc_time &, const sc_time &);