I am very new to gem5 and I come from C++. Perhaps this is a Python problem. So I was doing the tutorials and I do not understand how you can you know what attributes the System() object has. For example, I can see in "Creating a simple configuration script" that system has an attribute clk_domain, which corresponds to ClockedObject. But System is a class that inherits from SimObject, and none of them inherits from ClockedObject. Any help would be apprecieated. Thanks in advance.
gem5 uses code generation heavily.
Every SimObject Python class automatically generates a param C++ class under the build directory that gets passed as the constructor of the C++ object. This is described in further details at: https://cirosantilli.com/linux-kernel-module-cheat/#gem5-python-c-interaction and was also mentioned at: Viewing the parameters of the branch predictor in gem5
But basically, if you grep for generated C++ files in the build directory (ignore symlinks, which scons sets up to point back to the main source tree), you will be able to understand everything.
I haven't fully studied/understood how ClockedObject is used in particular, but the following should clarify the Python/C++ magic interaction part at least
The specific case of ClockedObject.clk_domain
, the default value for the parameter is hte magic Parent.clk_domain
, which links it to its parent's (in the SimObject tree) clk_domain
by default if another value is not given:
class ClockedObject(SimObject):
type = 'ClockedObject'
abstract = True
cxx_header = "sim/clocked_object.hh"
# The clock domain this clocked object belongs to, inheriting the
# parent's clock domain by default
clk_domain = Param.ClockDomain(Parent.clk_domain, "Clock domain")
# Power model for this ClockedObject
power_model = VectorParam.PowerModel([], "Power models")
power_state = Param.PowerState(PowerState(), "Power state")
The autogenerated class from that is build/ARM/params/ClockedObject.hh
is:
struct ClockedObjectParams
: public SimObjectParams
{
ClockDomain * clk_domain;
std::vector< PowerModel * > power_model;
PowerState * power_state;
};
and the corresponding pybind11 bindings link that object from python to C++:
static void
module_init(py::module &m_internal)
{
py::module m = m_internal.def_submodule("param_ClockedObject");
py::class_<ClockedObjectParams, SimObjectParams, std::unique_ptr<ClockedObjectParams, py::nodelete>>(m, "ClockedObjectParams")
.def_readwrite("clk_domain", &ClockedObjectParams::clk_domain)
.def_readwrite("power_model", &ClockedObjectParams::power_model)
.def_readwrite("power_state", &ClockedObjectParams::power_state)
;
py::class_<ClockedObject, SimObject, std::unique_ptr<ClockedObject, py::nodelete>>(m, "ClockedObject")
;
}
static EmbeddedPyBind embed_obj("ClockedObject", module_init, "SimObject");
and then when the C++ ClockedObject
object gets created (this is also from the Python via bindings after the full SimObject tree has been built), it receives ClockedObjectParams
as input at src/sim/clock_domain.hh which contains:
class ClockDomain : public SimObject
{
public:
typedef ClockDomainParams Params;
ClockDomain(const Params *p, VoltageDomain *voltage_domain);
Looking at fs.py, clk_domain
is actually a SrcClockDomain
initialized as:
# Create a source clock for the system and set the clock period
test_sys.clk_domain = SrcClockDomain(clock = options.sys_clock,
voltage_domain = test_sys.voltage_domain)
but things are analogous, there is a Python SrcClockDomain
which inherits from ClockDomain
and corresponding C++ classes.
Observed in gem5 3ca404da175a66e0b958165ad75eb5f54cb5e772.