diff -r afe0a546336f -r a04648a0d2c6 src/sim/clock_domain.hh --- a/src/sim/clock_domain.hh Thu Jun 06 22:40:41 2013 +0100 +++ b/src/sim/clock_domain.hh Thu Jun 06 22:42:48 2013 +0100 @@ -53,26 +53,52 @@ #include "sim/sim_object.hh" /** + * Forward declaration + */ +class DerivedClockDomain; + +/** * The ClockDomain provides clock to group of clocked objects bundled * under the same clock domain. The clock domains provide support for - * a hierarchial structure source and derived domains. + * a hierarchial structure with source and derived domains. */ class ClockDomain : public SimObject { + protected: + + /** + * Pre-computed clock period in ticks. This is populated by the + * inheriting classes based on how their period is determined. + */ + Tick _clockPeriod; + + /** + * Pointers to potential derived clock domains so we can propagate + * changes. + */ + std::vector children; + public: typedef ClockDomainParams Params; - ClockDomain(const Params *p) : SimObject(p) {} - - virtual ~ClockDomain() {} + ClockDomain(const Params *p) : SimObject(p), _clockPeriod(0) {} /** * Get the clock period. * * @return Clock period in ticks */ - virtual Tick clockPeriod() const = 0; + inline Tick clockPeriod() const { return _clockPeriod; } + + /** + * Add a derived domain. + * + * @param Derived domain to add as a child + */ + void addDerivedDomain(DerivedClockDomain *clock_domain) + { children.push_back(clock_domain); } + }; /** @@ -89,24 +115,11 @@ SrcClockDomain(const Params *p); /** - * Get the clock period. - * - * @return Clock period in ticks - */ - Tick clockPeriod() const; - - /** * Set new clock value * @param clock The new clock period in ticks */ - void clockPeriod(Tick clock); + void clockPeriod(Tick clock_period); - private: - - /** - * Clock period expressed in ticks - */ - Tick _clock; }; /** @@ -124,18 +137,19 @@ DerivedClockDomain(const Params *p); /** - * Get the clock period. - * - * @return Clock period in ticks + * Called by the parent clock domain to propagate changes. This + * also involves propagating the change further to any children of + * the derived domain itself. */ - Tick clockPeriod() const; + void updateClockPeriod(); private: /** - * Reference to the parents clock domain this clock domain belongs to + * Reference to the parent clock domain this clock domain derives + * its clock period from */ - ClockDomain &parentClockDomain; + ClockDomain &parent; /** * Local clock divider of the domain diff -r afe0a546336f -r a04648a0d2c6 src/sim/clock_domain.cc --- a/src/sim/clock_domain.cc Thu Jun 06 22:40:41 2013 +0100 +++ b/src/sim/clock_domain.cc Thu Jun 06 22:42:48 2013 +0100 @@ -36,6 +36,7 @@ * * Authors: Vasileios Spiliopoulos * Akash Bagdia + * Andreas Hansson */ #include "debug/ClockDomain.hh" @@ -44,27 +45,28 @@ #include "params/SrcClockDomain.hh" #include "sim/clock_domain.hh" -Tick -SrcClockDomain::clockPeriod() const +SrcClockDomain::SrcClockDomain(const Params *p) : ClockDomain(p) { - return _clock; -} - -SrcClockDomain::SrcClockDomain(const Params *p) : ClockDomain(p), - _clock(p->clock) -{ - if (_clock == 0) { - fatal("%s has a clock period of zero\n", name()); - } + clockPeriod(p->clock); } void -SrcClockDomain::clockPeriod(Tick clock) +SrcClockDomain::clockPeriod(Tick clock_period) { - _clock = clock; + if (clock_period == 0) { + fatal("%s has a clock period of zero\n", name()); + } + + _clockPeriod = clock_period; DPRINTF(ClockDomain, - "Setting clock period to %d for clock source %s\n", _clock, name()); + "Setting clock period to %d ticks for source clock %s\n", + _clockPeriod, name()); + + // inform any derived clocks they need to updated their period + for (auto c = children.begin(); c != children.end(); ++c) { + (*c)->updateClockPeriod(); + } } SrcClockDomain * @@ -75,7 +77,7 @@ DerivedClockDomain::DerivedClockDomain(const Params *p) : ClockDomain(p), - parentClockDomain(*p->clk_domain), + parent(*p->clk_domain), clockDivider(p->clk_divider) { // Ensure that clock divider setting works as frequency divider and never @@ -83,12 +85,30 @@ if (clockDivider < 1) { fatal("Clock divider param cannot be less than 1"); } + + // let the parent keep track of this derived domain so that it can + // propagate changes + parent.addDerivedDomain(this); + + // update our clock period based on the parents clock + updateClockPeriod(); } -Tick -DerivedClockDomain::clockPeriod() const +void +DerivedClockDomain::updateClockPeriod() { - return parentClockDomain.clockPeriod() * clockDivider; + // recalculate the clock period, relying on the fact that changes + // propagate downwards in the tree + _clockPeriod = parent.clockPeriod() * clockDivider; + + DPRINTF(ClockDomain, + "Setting clock period to %d ticks for derived clock %s\n", + _clockPeriod, name()); + + // inform any derived clocks + for (auto c = children.begin(); c != children.end(); ++c) { + (*c)->updateClockPeriod(); + } } DerivedClockDomain *