sim: Use the Temperature type in power/thermal models
authorAndreas Sandberg <andreas.sandberg@arm.com>
Wed, 20 Jan 2021 15:20:35 +0000 (15:20 +0000)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 26 Jan 2021 16:00:14 +0000 (16:00 +0000)
The thermal models currently work on temperatures in Celsius stored in
plain doubles. Switch to using Temperature instead and internal
processing in Kelvin. There should be no impact on the result since
all thermal processes work on temperature deltas.

Change-Id: I22d0261ae102f30d86051f24a2d88b067b321c91
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/39455
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>

src/dev/arm/rv_ctrl.cc
src/sim/power/mathexpr_powermodel.cc
src/sim/power/power_model.cc
src/sim/power/power_model.hh
src/sim/power/thermal_domain.cc
src/sim/power/thermal_domain.hh
src/sim/power/thermal_model.cc
src/sim/power/thermal_model.hh
src/sim/power/thermal_node.hh

index 2d80bc218ea70f10c53392252d431afdacf5d295..6cacb4dce89b1a0f3682f4a3314a0cf0c0755a0c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010,2013,2015 ARM Limited
+ * Copyright (c) 2010, 2013, 2015, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -304,7 +304,7 @@ RealViewTemperatureSensor::read() const
     // Temperature reported in uC
     ThermalModel * tm = system->getThermalModel();
     if (tm) {
-        double t = tm->getTemp();
+        double t = tm->getTemperature().toCelsius();
         if (t < 0)
             warn("Temperature below zero!\n");
         return fmax(0, t) * 1000000;
index 4f3f927354e9535da83f4e137f9a68b767ecb2ce..e66d8d99357d41791b4adccb9cdf70da4ee93adc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, 2020 ARM Limited
+ * Copyright (c) 2016-2017, 2020-2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -86,7 +86,7 @@ MathExprPowerModel::getStatValue(const std::string &name) const
 
     // Automatic variables:
     if (name == "temp") {
-        return _temp;
+        return _temp.toCelsius();
     } else if (name == "voltage") {
         return clocked_object->voltage();
     } else if (name=="clock_period") {
index 42515ace8681f5894018239e4aeaebe02c0cc9b3..e79ecbcd0a701a54980062fc5d1ad98693d8af19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018 ARM Limited
+ * Copyright (c) 2016-2018, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -66,7 +66,7 @@ PowerModel::PowerModel(const Params &p)
     // The temperature passed here will be overwritten, if there is
     // a thermal model present
     for (auto & pms: states_pm){
-        pms->setTemperature(p.ambient_temp.toCelsius());
+        pms->setTemperature(p.ambient_temp);
     }
 
     dynamicPower
@@ -86,7 +86,7 @@ PowerModel::setClockedObject(ClockedObject * clkobj)
 }
 
 void
-PowerModel::thermalUpdateCallback(const double & temp)
+PowerModel::thermalUpdateCallback(const Temperature &temp)
 {
     for (auto & pms: states_pm)
         pms->setTemperature(temp);
index e6f54311ace53b34c9bf6eb9412f3f937983a125..3a0fc644549af825f55dd7911a9729db850e3dce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018 ARM Limited
+ * Copyright (c) 2016, 2018, 2021 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -39,6 +39,7 @@
 #define __SIM_POWER_POWER_MODEL_HH__
 
 #include "base/statistics.hh"
+#include "base/temperature.hh"
 #include "enums/PMType.hh"
 #include "params/PowerModel.hh"
 #include "params/PowerModelState.hh"
@@ -75,9 +76,9 @@ class PowerModelState : public SimObject
     /**
      * Temperature update.
      *
-     * @param temp Current temperature of the HW part (Celsius)
+     * @param temp Current temperature of the HW part
      */
-    virtual void setTemperature(double temp) { _temp = temp; }
+    virtual void setTemperature(Temperature temp) { _temp = temp; }
 
     void setClockedObject(ClockedObject * clkobj) {
         clocked_object = clkobj;
@@ -86,7 +87,7 @@ class PowerModelState : public SimObject
   protected:
 
     /** Current temperature */
-    double _temp;
+    Temperature _temp;
 
     /** The clocked object we belong to */
     ClockedObject * clocked_object;
@@ -125,18 +126,18 @@ class PowerModel : public SimObject
 
     virtual void regProbePoints();
 
-    void thermalUpdateCallback(const double & temp);
+    void thermalUpdateCallback(const Temperature &temp);
 
   protected:
     /** Listener class to catch thermal events */
-    class ThermalProbeListener : public ProbeListenerArgBase<double>
+    class ThermalProbeListener : public ProbeListenerArgBase<Temperature>
     {
       public:
         ThermalProbeListener(PowerModel &_pm, ProbeManager *pm,
                       const std::string &name)
             : ProbeListenerArgBase(pm, name), pm(_pm) {}
 
-        void notify(const double &temp)
+        void notify(const Temperature &temp)
         {
             pm.thermalUpdateCallback(temp);
         }
index b0868becfe841c51a2bc33f27283a695192f1622..2d9076ba4f48d39712824acfb6c2f99219ecb959 100644 (file)
 #include "sim/sub_system.hh"
 
 ThermalDomain::ThermalDomain(const Params &p)
-    : SimObject(p), _initTemperature(p.initial_temperature.toCelsius()),
+    : SimObject(p), _initTemperature(p.initial_temperature),
     node(NULL), subsystem(NULL),
     ADD_STAT(currentTemp, "Temperature in centigrade degrees")
 {
     currentTemp
-        .method(this, &ThermalDomain::currentTemperature);
+        .functor([this]() { return currentTemperature().toCelsius(); });
 }
 
-double
+Temperature
 ThermalDomain::currentTemperature() const
 {
     return node->temp;
@@ -69,8 +69,8 @@ ThermalDomain::setSubSystem(SubSystem * ss)
     assert(!this->subsystem);
     this->subsystem = ss;
 
-    ppThermalUpdate = new ProbePointArg<double>(subsystem->getProbeManager(),
-                                                "thermalUpdate");
+    ppThermalUpdate = new ProbePointArg<Temperature>(
+        subsystem->getProbeManager(), "thermalUpdate");
 }
 
 void
index 9da753e85b439f84563bed968e6f028c76204efb..dcec15f4d02b60b230da4f7492b43fc1c834ce2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 ARM Limited
+ * Copyright (c) 2015, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -41,6 +41,7 @@
 #include <vector>
 
 #include "base/statistics.hh"
+#include "base/temperature.hh"
 #include "params/ThermalDomain.hh"
 #include "sim/power/thermal_entity.hh"
 #include "sim/power/thermal_node.hh"
@@ -66,14 +67,14 @@ class ThermalDomain : public SimObject, public ThermalEntity
      *
      * @return Initial temperature of the domain
      */
-    double initialTemperature() const { return _initTemperature; }
+    Temperature initialTemperature() const { return _initTemperature; }
 
     /**
      * Get the current temperature.
      *
-     * @return Initial temperature of the domain
+     * @return current temperature of the domain
      */
-    double currentTemperature() const;
+    Temperature currentTemperature() const;
 
     /** Set/Get circuit node associated with this domain */
     void setNode(ThermalNode * n) { node = n; }
@@ -94,7 +95,7 @@ class ThermalDomain : public SimObject, public ThermalEntity
     void setSubSystem(SubSystem * ss);
 
   private:
-    double _initTemperature;
+    const Temperature _initTemperature;
     ThermalNode * node;
     SubSystem * subsystem;
 
@@ -102,7 +103,7 @@ class ThermalDomain : public SimObject, public ThermalEntity
     Stats::Value currentTemp;
 
     /** Probe to signal for temperature changes in this domain */
-    ProbePointArg<double> *ppThermalUpdate;
+    ProbePointArg<Temperature> *ppThermalUpdate;
 
 };
 
index c57e284c9c99681a5a4b8004c7e29237fecc9260..37229569ada60d73377e08d3e69d7e3202f50238 100644 (file)
@@ -51,7 +51,7 @@
  * ThermalReference
  */
 ThermalReference::ThermalReference(const Params &p)
-    : SimObject(p), _temperature(p.temperature.toCelsius()), node(NULL)
+    : SimObject(p), _temperature(p.temperature), node(NULL)
 {
 }
 
@@ -81,12 +81,12 @@ ThermalResistor::getEquation(ThermalNode * n, unsigned nnodes,
         return eq;
 
     if (node1->isref)
-        eq[eq.cnt()] += -node1->temp / _resistance;
+        eq[eq.cnt()] += -node1->temp.toKelvin() / _resistance;
     else
         eq[node1->id] += -1.0f / _resistance;
 
     if (node2->isref)
-        eq[eq.cnt()] += node2->temp / _resistance;
+        eq[eq.cnt()] += node2->temp.toKelvin() / _resistance;
     else
         eq[node2->id] += 1.0f / _resistance;
 
@@ -116,15 +116,16 @@ ThermalCapacitor::getEquation(ThermalNode * n, unsigned nnodes,
     if (n != node1 && n != node2)
         return eq;
 
-    eq[eq.cnt()] += _capacitance / step * (node1->temp - node2->temp);
+    eq[eq.cnt()] += _capacitance / step *
+        (node1->temp - node2->temp).toKelvin();
 
     if (node1->isref)
-        eq[eq.cnt()] += _capacitance / step * (-node1->temp);
+        eq[eq.cnt()] += _capacitance / step * (-node1->temp.toKelvin());
     else
         eq[node1->id] += -1.0f * _capacitance / step;
 
     if (node2->isref)
-        eq[eq.cnt()] += _capacitance / step * (node2->temp);
+        eq[eq.cnt()] += _capacitance / step * (node2->temp.toKelvin());
     else
         eq[node2->id] += 1.0f * _capacitance / step;
 
@@ -162,7 +163,7 @@ ThermalModel::doStep()
     // Get temperatures for this iteration
     std::vector <double> temps = ls.solve();
     for (unsigned i = 0; i < eq_nodes.size(); i++)
-        eq_nodes[i]->temp = temps[i];
+        eq_nodes[i]->temp = Temperature::fromKelvin(temps[i]);
 
     // Schedule next computation
     schedule(stepEvent, curTick() + SimClock::Int::s * _step);
@@ -233,11 +234,11 @@ ThermalModel::addResistor(ThermalResistor * r)
     entities.push_back(r);
 }
 
-double
-ThermalModel::getTemp() const
+Temperature
+ThermalModel::getTemperature() const
 {
     // Just pick the highest temperature
-    double temp = 0;
+    Temperature temp = Temperature::fromKelvin(0.0);
     for (auto & n : eq_nodes)
         temp = std::max(temp, n->temp);
     return temp;
index 95d0c7ae79794eef76be368bb121497e89087023..d3717dfb0b242ba8935e6421e97cf63241167e8a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 ARM Limited
+ * Copyright (c) 2015, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -40,6 +40,7 @@
 
 #include <vector>
 
+#include "base/temperature.hh"
 #include "sim/clocked_object.hh"
 #include "sim/power/thermal_domain.hh"
 #include "sim/power/thermal_entity.hh"
@@ -122,8 +123,8 @@ class ThermalReference : public SimObject, public ThermalEntity
     LinearEquation getEquation(ThermalNode * tn, unsigned n,
                                double step) const override;
 
-    /* Fixed temperature value in centigrate degrees */
-    const double _temperature;
+    /* Fixed temperature value */
+    const Temperature _temperature;
     /* Nodes connected to the resistor */
     ThermalNode * node;
 };
@@ -150,7 +151,7 @@ class ThermalModel : public ClockedObject
 
     void addNode(ThermalNode * n) { nodes.push_back(n); }
 
-    double getTemp() const;
+    Temperature getTemperature() const;
 
     void startup() override;
     void doStep();
index 68867b39eab72242dec6ea29ead5c933c082ec5b..e9d4096ca0c11e6c474e674a425c16cd4ee3c87e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 ARM Limited
+ * Copyright (c) 2015, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -38,6 +38,7 @@
 #ifndef __SIM_THERMAL_NODE_HH__
 #define __SIM_THERMAL_NODE_HH__
 
+#include "base/temperature.hh"
 #include "sim/sim_object.hh"
 
 struct ThermalNodeParams;
@@ -54,7 +55,7 @@ class ThermalNode : public SimObject
 
     int id;
     bool isref;
-    double temp;
+    Temperature temp;
 };
 
 #endif