sim: Use the Temperature type in power/thermal models
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>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -49,15 +49,15 @@
|
||||
#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
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user