mem: Explicitly check MSHR snoops for cases not dealt with
[gem5.git] / src / sim / clock_domain.hh
index c3f53e675fc7a73aae016c151a29b96cc123ac8c..71627434a2d7d2c32572d66fa53971f8fa4afd78 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013 Cornell University
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -36,6 +37,8 @@
  *
  * Authors: Vasileios Spiliopoulos
  *          Akash Bagdia
+ *          Christopher Torng
+ *          Stephan Diestelhorst
  */
 
 /**
@@ -46,6 +49,8 @@
 #ifndef __SIM_CLOCK_DOMAIN_HH__
 #define __SIM_CLOCK_DOMAIN_HH__
 
+#include <algorithm>
+
 #include "base/statistics.hh"
 #include "params/ClockDomain.hh"
 #include "params/DerivedClockDomain.hh"
  * Forward declaration
  */
 class DerivedClockDomain;
+class VoltageDomain;
+class Clocked;
 
 /**
  * The ClockDomain provides clock to group of clocked objects bundled
- * under the same clock domain. The clock domains provide support for
+ * under the same clock domain. The clock domains, in turn, are
+ * grouped into voltage domains. The clock domains provide support for
  * a hierarchial structure with source and derived domains.
  */
 class ClockDomain : public SimObject
 {
 
+  private:
+
+    /**
+     * Stat to report clock period of clock domain
+     */
+    Stats::Value currentClock;
+
   protected:
 
     /**
@@ -73,23 +88,66 @@ class ClockDomain : public SimObject
      */
     Tick _clockPeriod;
 
+    /**
+     * Voltage domain this clock domain belongs to
+     */
+    VoltageDomain *_voltageDomain;
+
     /**
      * Pointers to potential derived clock domains so we can propagate
      * changes.
      */
     std::vector<DerivedClockDomain*> children;
 
+    /**
+     * Pointers to members of this clock domain, so that when the clock
+     * period changes, we can update each member's tick.
+     */
+    std::vector<Clocked *> members;
+
   public:
 
     typedef ClockDomainParams Params;
-    ClockDomain(const Params *p) : SimObject(p), _clockPeriod(0) {}
+    ClockDomain(const Params *p, VoltageDomain *voltage_domain) :
+        SimObject(p),
+        _clockPeriod(0),
+        _voltageDomain(voltage_domain) {}
+
+    void regStats();
 
     /**
      * Get the clock period.
      *
      * @return Clock period in ticks
      */
-    inline Tick clockPeriod() const { return _clockPeriod; }
+    Tick clockPeriod() const { return _clockPeriod; }
+
+    /**
+     * Register a Clocked object with this ClockDomain.
+     *
+     * @param Clocked to add as a member
+     */
+    void registerWithClockDomain(Clocked *c)
+    {
+        assert(c != NULL);
+        assert(std::find(members.begin(), members.end(), c) == members.end());
+        members.push_back(c);
+    }
+
+    /**
+     * Get the voltage domain.
+     *
+     * @return Voltage domain this clock domain belongs to
+     */
+    inline VoltageDomain *voltageDomain() const { return _voltageDomain; }
+
+
+    /**
+     * Get the current voltage this clock domain operates at.
+     *
+     * @return Voltage applied to the clock domain
+     */
+    double voltage() const;
 
     /**
      * Add a derived domain.
@@ -104,7 +162,11 @@ class ClockDomain : public SimObject
 /**
  * The source clock domains provides the notion of a clock domain that is
  * connected to a tunable clock source. It maintains the clock period and
- * provides methods for setting/getting the clock.
+ * provides methods for setting/getting the clock and  configuration parameters
+ * for clock domain that handler is going to manage. This includes frequency
+ * values at various performance levels, domain id, and current performance
+ * level. Note that a performance level as requested by the software corresponds
+ * to one of the frequency operational points the domain can operate at.
  */
 class SrcClockDomain : public ClockDomain
 {
@@ -120,6 +182,88 @@ class SrcClockDomain : public ClockDomain
      */
     void clockPeriod(Tick clock_period);
 
+    // Explicitly import the otherwise hidden clockPeriod
+    using ClockDomain::clockPeriod;
+
+    typedef int32_t DomainID;
+    static const DomainID emptyDomainID = -1;
+
+    /**
+     * @return the domainID of the domain
+     */
+    uint32_t domainID() const { return _domainID; }
+
+    typedef uint32_t PerfLevel;
+    /**
+     * Checks whether the performance level requested exists in the current
+     * domain configuration
+     *
+     * @param the target performance level of the domain
+     *
+     * @return validity status of the given performance level
+     */
+    bool validPerfLevel(PerfLevel perf_level) const {
+        return perf_level < numPerfLevels();
+    }
+
+    /**
+     * Sets the current performance level of the domain
+     *
+     * @param perf_level the target performance level
+     */
+    void perfLevel(PerfLevel perf_level);
+
+    /**
+     * @return the current performance level of the domain
+     */
+    PerfLevel perfLevel() const { return _perfLevel; }
+
+    /**
+     * Get the number of available performance levels for this clock domain.
+     *
+     * @return Number of perf levels configured for this domain.
+     */
+    PerfLevel numPerfLevels() const {return freqOpPoints.size();}
+
+    /**
+     * @returns the clock period (expressed in ticks) for the current
+     * performance level
+     */
+    Tick clkPeriodAtPerfLevel() const { return freqOpPoints[perfLevel()]; }
+
+    Tick clkPeriodAtPerfLevel(PerfLevel perf_level) const
+    {
+        assert(validPerfLevel(perf_level));
+        return freqOpPoints[perf_level];
+    }
+
+    void startup() override;
+
+    void serialize(CheckpointOut &cp) const override;
+    void unserialize(CheckpointIn &cp) override;
+
+  private:
+    /**
+      * List of possible frequency operational points, should be in
+      * descending order
+      * An empty list corresponds to default frequency specified for its
+      * clock domain, overall implying NO DVFS
+      */
+    const std::vector<Tick> freqOpPoints;
+
+    /**
+      * Software recognizable id number for the domain, should be unique for
+      * each domain
+      */
+    const uint32_t _domainID;
+
+    /**
+      * Current performance level the domain is set to.
+      * The performance level corresponds to one selected frequency (and related
+      * voltage) from the supplied list of frequencies, with perfLevel = 0 being
+      * the fastest performance state.
+      */
+    PerfLevel _perfLevel;
 };
 
 /**