mem: Make the XBar responsible for tracking response routing
[gem5.git] / src / sim / voltage_domain.hh
index b2f6715cff5744e5a0719142c493c091fb14ed66..ab96abad84ff92cc917957c5ebaa786e608a0fff 100644 (file)
 #ifndef __SIM_VOLTAGE_DOMAIN_HH__
 #define __SIM_VOLTAGE_DOMAIN_HH__
 
+#include <vector>
+
 #include "base/statistics.hh"
 #include "params/VoltageDomain.hh"
+#include "sim/clock_domain.hh"
 #include "sim/sim_object.hh"
 
 /**
  */
 class VoltageDomain : public SimObject
 {
+  public:
 
-  private:
+    typedef VoltageDomainParams Params;
+    VoltageDomain(const Params *p);
+
+    typedef SrcClockDomain::PerfLevel PerfLevel;
 
     /**
-     * The voltage of the domain expressed in Volts
+     * Get the current voltage.
+     *
+     * @return Voltage of the domain
      */
-    double _voltage;
+    double voltage() const { return voltageOpPoints[_perfLevel]; }
 
     /**
-     * Stat for reporting voltage of the domain
+     * Get the voltage at specified performance level.
+     *
+     * @param perf_level Performance level for which the voltage is requested
+     * @return Voltage of the domain at specified performance level
      */
-    Stats::Value currentVoltage;
+    double voltage(PerfLevel perf_level) const
+    {
+        chatty_assert(perf_level < numVoltages(), "VoltageDomain %s "\
+                      "request for voltage perf level %u is outside "\
+                      "of numVoltages %u", name(), perf_level,
+                      numVoltages());
+        return voltageOpPoints[perf_level];
+    }
 
-  public:
+    uint32_t numVoltages() const { return (uint32_t)voltageOpPoints.size(); }
 
-    typedef VoltageDomainParams Params;
-    VoltageDomain(const Params *p);
+    /**
+     * Set the voltage point of the domain.
+     * @param Voltage value to be set
+     */
+    void perfLevel(PerfLevel perf_level);
 
     /**
-     * Get the current volate.
-     *
-     * @return Voltage of the domain
+     * Get the voltage point of the domain.
+     * @param Voltage value to be set
+     */
+    PerfLevel perfLevel() const { return _perfLevel; }
+
+    /**
+     * Register a SrcClockDomain with this voltage domain.
+     * @param src_clock_domain The SrcClockDomain to register.
+     */
+    void registerSrcClockDom(SrcClockDomain *src_clock_dom) {
+        assert(src_clock_dom->voltageDomain() == this);
+        srcClockChildren.push_back(src_clock_dom);
+    }
+
+    /**
+     * Startup has all SrcClockDomains registered with this voltage domain, so
+     * try to make sure that all perf level requests from them are met.
      */
-    inline double voltage() const { return _voltage; }
+    void startup();
 
     /**
-     * Set the voltage of the domain.
+     * Recomputes the highest (fastest, i.e., numerically lowest) requested
+     * performance level of all associated clock domains, and updates the
+     * performance level of this voltage domain to match.  This means that for
+     * two connected clock domains, one fast and one slow, the voltage domain
+     * will provide the voltage associated with the fast DVFS operation point.
+     * Must be called whenever a clock domain decides to swtich its performance
+     * level.
      *
-     * @param Voltage value to be set
+     * @return True, if the voltage was actually changed.
      */
-    void voltage(double voltage);
+    bool sanitiseVoltages();
 
     void regStats();
 
+    void serialize(std::ostream &os);
+    void unserialize(Checkpoint *cp, const std::string &section);
+  private:
+    typedef std::vector<double> Voltages;
+    /**
+     * List of possible minimum voltage at each of the frequency operational
+     * points, should be in descending order and same size as freqOpPoints.
+     * An empty list corresponds to default voltage specified for the voltage
+     * domain its clock domain belongs. The same voltage is applied for each
+     * freqOpPoints, overall implying NO DVS
+     */
+    const Voltages voltageOpPoints;
+    PerfLevel _perfLevel;
+
+    /**
+     * Stat for reporting voltage of the domain
+     */
+    Stats::Value currentVoltage;
+
+    /**
+     * List of associated SrcClockDomains that are connected to this voltage
+     * domain.
+     */
+    typedef std::vector<SrcClockDomain *> SrcClockChildren;
+    SrcClockChildren srcClockChildren;
 };
 
 #endif