sim: Push the global frequency management code into C++.
That makes it available when python is left out, and makes it available to c++ code without having to call back into python. Change-Id: If82e7e8eff526f2b957f84afe046e1d56fed4aa2 Reviewed-on: https://gem5-review.googlesource.com/c/14055 Reviewed-by: Srikant Bharadwaj <srikant.bharadwaj@amd.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -31,26 +31,14 @@ from __future__ import print_function
|
|||||||
import sys
|
import sys
|
||||||
from m5.util import warn
|
from m5.util import warn
|
||||||
|
|
||||||
tps = 1.0e12 # default to 1 THz (1 Tick == 1 ps)
|
# fix the global frequency
|
||||||
tps_fixed = False # once set to true, can't be changed
|
|
||||||
|
|
||||||
# fix the global frequency and tell C++ about it
|
|
||||||
def fixGlobalFrequency():
|
def fixGlobalFrequency():
|
||||||
import _m5.core
|
import _m5.core
|
||||||
global tps, tps_fixed
|
_m5.core.fixClockFrequency()
|
||||||
if not tps_fixed:
|
|
||||||
tps_fixed = True
|
|
||||||
_m5.core.setClockFrequency(int(tps))
|
|
||||||
print("Global frequency set at %d ticks per second" % int(tps))
|
|
||||||
|
|
||||||
def setGlobalFrequency(ticksPerSecond):
|
def setGlobalFrequency(ticksPerSecond):
|
||||||
from m5.util import convert
|
from m5.util import convert
|
||||||
|
import _m5.core
|
||||||
global tps, tps_fixed
|
|
||||||
|
|
||||||
if tps_fixed:
|
|
||||||
raise AttributeError, \
|
|
||||||
"Global frequency already fixed at %f ticks/s." % tps
|
|
||||||
|
|
||||||
if isinstance(ticksPerSecond, (int, long)):
|
if isinstance(ticksPerSecond, (int, long)):
|
||||||
tps = ticksPerSecond
|
tps = ticksPerSecond
|
||||||
@@ -61,17 +49,20 @@ def setGlobalFrequency(ticksPerSecond):
|
|||||||
else:
|
else:
|
||||||
raise TypeError, \
|
raise TypeError, \
|
||||||
"wrong type '%s' for ticksPerSecond" % type(ticksPerSecond)
|
"wrong type '%s' for ticksPerSecond" % type(ticksPerSecond)
|
||||||
|
_m5.core.setClockFrequency(tps)
|
||||||
|
|
||||||
# how big does a rounding error need to be before we warn about it?
|
# how big does a rounding error need to be before we warn about it?
|
||||||
frequency_tolerance = 0.001 # 0.1%
|
frequency_tolerance = 0.001 # 0.1%
|
||||||
|
|
||||||
def fromSeconds(value):
|
def fromSeconds(value):
|
||||||
|
import _m5.core
|
||||||
|
|
||||||
if not isinstance(value, float):
|
if not isinstance(value, float):
|
||||||
raise TypeError, "can't convert '%s' to type tick" % type(value)
|
raise TypeError, "can't convert '%s' to type tick" % type(value)
|
||||||
|
|
||||||
# once someone needs to convert to seconds, the global frequency
|
# once someone needs to convert to seconds, the global frequency
|
||||||
# had better be fixed
|
# had better be fixed
|
||||||
if not tps_fixed:
|
if not _m5.core.clockFrequencyFixed():
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
"In order to do conversions, the global frequency must be fixed"
|
"In order to do conversions, the global frequency must be fixed"
|
||||||
|
|
||||||
@@ -79,7 +70,7 @@ def fromSeconds(value):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
# convert the value from time to ticks
|
# convert the value from time to ticks
|
||||||
value *= tps
|
value *= _m5.core.getClockFrequency()
|
||||||
|
|
||||||
int_value = int(round(value))
|
int_value = int(round(value))
|
||||||
err = (value - int_value) / value
|
err = (value - int_value) / value
|
||||||
|
|||||||
@@ -245,7 +245,11 @@ pybind_init_core(py::module &m_native)
|
|||||||
.def("seedRandom", [](uint64_t seed) { random_mt.init(seed); })
|
.def("seedRandom", [](uint64_t seed) { random_mt.init(seed); })
|
||||||
|
|
||||||
|
|
||||||
|
.def("fixClockFrequency", &fixClockFrequency)
|
||||||
|
.def("clockFrequencyFixed", &clockFrequencyFixed)
|
||||||
|
|
||||||
.def("setClockFrequency", &setClockFrequency)
|
.def("setClockFrequency", &setClockFrequency)
|
||||||
|
.def("getClockFrequency", &getClockFrequency)
|
||||||
.def("curTick", curTick)
|
.def("curTick", curTick)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/callback.hh"
|
#include "base/callback.hh"
|
||||||
|
#include "base/cprintf.hh"
|
||||||
|
#include "base/logging.hh"
|
||||||
#include "base/output.hh"
|
#include "base/output.hh"
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
@@ -69,11 +71,23 @@ Tick ps;
|
|||||||
|
|
||||||
} // namespace SimClock
|
} // namespace SimClock
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool _clockFrequencyFixed = false;
|
||||||
|
|
||||||
|
// Default to 1 THz (1 Tick == 1 ps)
|
||||||
|
Tick _ticksPerSecond = 1e12;
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
void
|
void
|
||||||
setClockFrequency(Tick ticksPerSecond)
|
fixClockFrequency()
|
||||||
{
|
{
|
||||||
|
if (_clockFrequencyFixed)
|
||||||
|
return;
|
||||||
|
|
||||||
using namespace SimClock;
|
using namespace SimClock;
|
||||||
Frequency = ticksPerSecond;
|
Frequency = _ticksPerSecond;
|
||||||
Float::s = static_cast<double>(Frequency);
|
Float::s = static_cast<double>(Frequency);
|
||||||
Float::ms = Float::s / 1.0e3;
|
Float::ms = Float::s / 1.0e3;
|
||||||
Float::us = Float::s / 1.0e6;
|
Float::us = Float::s / 1.0e6;
|
||||||
@@ -91,7 +105,20 @@ setClockFrequency(Tick ticksPerSecond)
|
|||||||
Int::ns = Int::us / 1000;
|
Int::ns = Int::us / 1000;
|
||||||
Int::ps = Int::ns / 1000;
|
Int::ps = Int::ns / 1000;
|
||||||
|
|
||||||
|
cprintf("Global frequency set at %d ticks per second\n", _ticksPerSecond);
|
||||||
|
|
||||||
|
_clockFrequencyFixed = true;
|
||||||
}
|
}
|
||||||
|
bool clockFrequencyFixed() { return _clockFrequencyFixed; }
|
||||||
|
|
||||||
|
void
|
||||||
|
setClockFrequency(Tick tps)
|
||||||
|
{
|
||||||
|
panic_if(_clockFrequencyFixed,
|
||||||
|
"Global frequency already fixed at %f ticks/s.", _ticksPerSecond);
|
||||||
|
_ticksPerSecond = tps;
|
||||||
|
}
|
||||||
|
Tick getClockFrequency() { return _ticksPerSecond; }
|
||||||
|
|
||||||
void
|
void
|
||||||
setOutputDir(const string &dir)
|
setOutputDir(const string &dir)
|
||||||
|
|||||||
@@ -91,7 +91,12 @@ extern Tick ps; ///< picosecond
|
|||||||
} // namespace Int
|
} // namespace Int
|
||||||
} // namespace SimClock
|
} // namespace SimClock
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
void fixClockFrequency();
|
||||||
|
bool clockFrequencyFixed();
|
||||||
|
|
||||||
void setClockFrequency(Tick ticksPerSecond);
|
void setClockFrequency(Tick ticksPerSecond);
|
||||||
|
Tick getClockFrequency(); // Ticks per second.
|
||||||
|
|
||||||
void setOutputDir(const std::string &dir);
|
void setOutputDir(const std::string &dir);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user