Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/12215

Change subject: systemc: Implement a significant portion of sc_clock.
......................................................................

systemc: Implement a significant portion of sc_clock.

Change-Id: Ic195f46ac13b46a02c86a5fc8d90ba66a415a9c8
---
M src/systemc/channel/sc_clock.cc
M src/systemc/ext/channel/sc_clock.hh
2 files changed, 122 insertions(+), 55 deletions(-)



diff --git a/src/systemc/channel/sc_clock.cc b/src/systemc/channel/sc_clock.cc
index 65f1f10..6736e57 100644
--- a/src/systemc/channel/sc_clock.cc
+++ b/src/systemc/channel/sc_clock.cc
@@ -28,84 +28,121 @@
  */

 #include "base/logging.hh"
+#include "base/types.hh"
+#include "sim/core.hh"
+#include "sim/eventq.hh"
+#include "systemc/core/kernel.hh"
+#include "systemc/core/sched_event.hh"
+#include "systemc/core/scheduler.hh"
 #include "systemc/ext/channel/sc_clock.hh"
 #include "systemc/ext/core/sc_module.hh" // for sc_gen_unique_name

+namespace sc_gem5
+{
+
+class ClockTick : public ScEvent
+{
+  private:
+    ::sc_core::sc_clock *clock;
+    ::sc_core::sc_time _period;
+    std::string _name;
+    Process *p;
+    ProcessMemberFuncWrapper<::sc_core::sc_clock> funcWrapper;
+    std::string _procName;
+
+  public:
+    ClockTick(::sc_core::sc_clock *clock, bool to,
+            ::sc_core::sc_time _period) :
+        ScEvent([this]() { tick(); }),
+        clock(clock), _period(_period), _name(clock->name()),
+        funcWrapper(clock, to ? &::sc_core::sc_clock::tickUp :
+                                &::sc_core::sc_clock::tickDown)
+    {
+        _name += (to ? ".up_tick" : ".down_tick");
+        _procName = _name + ".p";
+        p = newMethodProcess(_procName.c_str(), &funcWrapper);
+        scheduler.dontInitialize(p);
+    }
+
+    ~ClockTick()
+    {
+        if (scheduled())
+            scheduler.deschedule(this);
+        p->popListNode();
+    }
+
+    void
+    tick()
+    {
+        scheduler.schedule(this, _period);
+        p->ready();
+    }
+};
+
+};
+
 namespace sc_core
 {

 sc_clock::sc_clock() :
-        sc_interface(), sc_signal<bool>(sc_gen_unique_name("clock"))
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+    sc_clock(sc_gen_unique_name("clock"), sc_time(1.0, SC_NS),
+            0.5, SC_ZERO_TIME, true)
+{}

-sc_clock::sc_clock(const char *name) : sc_interface(), sc_signal<bool>(name)
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+sc_clock::sc_clock(const char *name) :
+    sc_clock(name, sc_time(1.0, SC_NS), 0.5, SC_ZERO_TIME, true)
+{}

 sc_clock::sc_clock(const char *name, const sc_time &period,
                    double duty_cycle, const sc_time &start_time,
-                   bool posedge_first)
+                   bool posedge_first) :
+    sc_interface(), sc_signal<bool>(name, posedge_first ? false : true),
+    _period(period), _dutyCycle(duty_cycle), _startTime(start_time),
+    _posedgeFirst(posedge_first)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _gem5UpEdge = new ::sc_gem5::ClockTick(this, true, period);
+    _gem5DownEdge = new ::sc_gem5::ClockTick(this, false, period);
 }

sc_clock::sc_clock(const char *name, double period_v, sc_time_unit period_tu,
-                   double duty_cycle)
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+                   double duty_cycle) :
+    sc_clock(name, sc_time(period_v, period_tu), duty_cycle, SC_ZERO_TIME,
+            true)
+{}

sc_clock::sc_clock(const char *name, double period_v, sc_time_unit period_tu,
                    double duty_cycle, double start_time_v,
-                   sc_time_unit start_time_tu, bool posedge_first)
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+                   sc_time_unit start_time_tu, bool posedge_first) :
+    sc_clock(name, sc_time(period_v, period_tu), duty_cycle,
+            sc_time(start_time_v, start_time_tu), posedge_first)
+{}

 sc_clock::sc_clock(const char *name, double period, double duty_cycle,
-                   double start_time, bool posedge_first)
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+                   double start_time, bool posedge_first) :
+    sc_clock(name, sc_time(period, true), duty_cycle,
+            sc_time(start_time, true), posedge_first)
+{}

-sc_clock::~sc_clock() {}
+sc_clock::~sc_clock()
+{
+    if (_gem5UpEdge->scheduled())
+        ::sc_gem5::scheduler.deschedule(_gem5UpEdge);
+    if (_gem5DownEdge->scheduled())
+        ::sc_gem5::scheduler.deschedule(_gem5DownEdge);
+    delete _gem5UpEdge;
+    delete _gem5DownEdge;
+}

 void
 sc_clock::write(const bool &)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    panic("write() called on sc_clock.");
 }

-const sc_time &
-sc_clock::period() const
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return *(const sc_time *)nullptr;
-}
-
-double
-sc_clock::duty_cycle() const
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return 0.0;
-}
-
-const sc_time &
-sc_clock::start_time() const
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return *(const sc_time *)nullptr;
-}
-
-bool
-sc_clock::posedge_first() const
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return false;
-}
+const sc_time &sc_clock::period() const { return _period; }
+double sc_clock::duty_cycle() const { return _dutyCycle; }
+const sc_time &sc_clock::start_time() const { return _startTime; }
+bool sc_clock::posedge_first() const { return _posedgeFirst; }

 const sc_time &
 sc_clock::time_stamp()
@@ -114,8 +151,18 @@
     return *(const sc_time *)nullptr;
 }

-const char *sc_clock::kind() const { return "sc_clock"; }
-
-void sc_clock::before_end_of_elaboration() {}
+void
+sc_clock::before_end_of_elaboration()
+{
+    if (_posedgeFirst) {
+        ::sc_gem5::scheduler.schedule(_gem5UpEdge, _startTime);
+        ::sc_gem5::scheduler.schedule(_gem5DownEdge,
+                _startTime + _period * _dutyCycle);
+    } else {
+        ::sc_gem5::scheduler.schedule(_gem5DownEdge, _startTime);
+        ::sc_gem5::scheduler.schedule(_gem5UpEdge,
+                _startTime + _period * (1.0 - _dutyCycle));
+    }
+}

 } // namespace sc_core
diff --git a/src/systemc/ext/channel/sc_clock.hh b/src/systemc/ext/channel/sc_clock.hh
index 30895ce..3713394 100644
--- a/src/systemc/ext/channel/sc_clock.hh
+++ b/src/systemc/ext/channel/sc_clock.hh
@@ -33,6 +33,13 @@
 #include "../core/sc_time.hh"
 #include "sc_signal.hh"

+namespace sc_gem5
+{
+
+class ClockTick;
+
+} // namespace sc_gem5
+
 namespace sc_core
 {

@@ -74,15 +81,28 @@
     // Nonstandard
     static const sc_time &time_stamp();

-    virtual const char *kind() const;
+    virtual const char *kind() const { return "sc_clock"; }

   protected:
     virtual void before_end_of_elaboration();

   private:
+    friend class ::sc_gem5::ClockTick;
+
     // Disabled
     sc_clock(const sc_clock &) : sc_interface(), sc_signal<bool>() {}
     sc_clock &operator = (const sc_clock &) { return *this; }
+
+    sc_time _period;
+    double _dutyCycle;
+    sc_time _startTime;
+    bool _posedgeFirst;
+
+    ::sc_gem5::ClockTick *_gem5UpEdge;
+    ::sc_gem5::ClockTick *_gem5DownEdge;
+
+    void tickUp() { sc_signal<bool>::write(true); }
+    void tickDown() { sc_signal<bool>::write(false); }
 };

 typedef sc_in<bool> sc_in_clk;

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12215
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: Ic195f46ac13b46a02c86a5fc8d90ba66a415a9c8
Gerrit-Change-Number: 12215
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to