19793Sakash.bagdia@arm.com/*
210249Sstephan.diestelhorst@arm.com * Copyright (c) 2013-2014 ARM Limited
310000Sclt67@cornell.edu * Copyright (c) 2013 Cornell University
49793Sakash.bagdia@arm.com * All rights reserved
59793Sakash.bagdia@arm.com *
69793Sakash.bagdia@arm.com * The license below extends only to copyright in the software and shall
79793Sakash.bagdia@arm.com * not be construed as granting a license to any other intellectual
89793Sakash.bagdia@arm.com * property including but not limited to intellectual property relating
99793Sakash.bagdia@arm.com * to a hardware implementation of the functionality of the software
109793Sakash.bagdia@arm.com * licensed hereunder.  You may use the software subject to the license
119793Sakash.bagdia@arm.com * terms below provided that you ensure that this notice is replicated
129793Sakash.bagdia@arm.com * unmodified and in its entirety in all distributions of the software,
139793Sakash.bagdia@arm.com * modified or unmodified, in source code or in binary form.
149793Sakash.bagdia@arm.com *
159793Sakash.bagdia@arm.com * Redistribution and use in source and binary forms, with or without
169793Sakash.bagdia@arm.com * modification, are permitted provided that the following conditions are
179793Sakash.bagdia@arm.com * met: redistributions of source code must retain the above copyright
189793Sakash.bagdia@arm.com * notice, this list of conditions and the following disclaimer;
199793Sakash.bagdia@arm.com * redistributions in binary form must reproduce the above copyright
209793Sakash.bagdia@arm.com * notice, this list of conditions and the following disclaimer in the
219793Sakash.bagdia@arm.com * documentation and/or other materials provided with the distribution;
229793Sakash.bagdia@arm.com * neither the name of the copyright holders nor the names of its
239793Sakash.bagdia@arm.com * contributors may be used to endorse or promote products derived from
249793Sakash.bagdia@arm.com * this software without specific prior written permission.
259793Sakash.bagdia@arm.com *
269793Sakash.bagdia@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
279793Sakash.bagdia@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
289793Sakash.bagdia@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
299793Sakash.bagdia@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
309793Sakash.bagdia@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
319793Sakash.bagdia@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
329793Sakash.bagdia@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
339793Sakash.bagdia@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
349793Sakash.bagdia@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
359793Sakash.bagdia@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
369793Sakash.bagdia@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
379793Sakash.bagdia@arm.com *
389793Sakash.bagdia@arm.com * Authors: Vasileios Spiliopoulos
399793Sakash.bagdia@arm.com *          Akash Bagdia
4010000Sclt67@cornell.edu *          Christopher Torng
4110249Sstephan.diestelhorst@arm.com *          Stephan Diestelhorst
429793Sakash.bagdia@arm.com */
439793Sakash.bagdia@arm.com
449793Sakash.bagdia@arm.com/**
459793Sakash.bagdia@arm.com * @file
469793Sakash.bagdia@arm.com * ClockDomain declarations.
479793Sakash.bagdia@arm.com */
489793Sakash.bagdia@arm.com
499793Sakash.bagdia@arm.com#ifndef __SIM_CLOCK_DOMAIN_HH__
509793Sakash.bagdia@arm.com#define __SIM_CLOCK_DOMAIN_HH__
519793Sakash.bagdia@arm.com
5210000Sclt67@cornell.edu#include <algorithm>
5310000Sclt67@cornell.edu
549793Sakash.bagdia@arm.com#include "base/statistics.hh"
559793Sakash.bagdia@arm.com#include "params/ClockDomain.hh"
569793Sakash.bagdia@arm.com#include "params/DerivedClockDomain.hh"
579793Sakash.bagdia@arm.com#include "params/SrcClockDomain.hh"
589793Sakash.bagdia@arm.com#include "sim/sim_object.hh"
599793Sakash.bagdia@arm.com
609793Sakash.bagdia@arm.com/**
619793Sakash.bagdia@arm.com * Forward declaration
629793Sakash.bagdia@arm.com */
639793Sakash.bagdia@arm.comclass DerivedClockDomain;
649827Sakash.bagdia@arm.comclass VoltageDomain;
6511009Sandreas.sandberg@arm.comclass Clocked;
669793Sakash.bagdia@arm.com
679793Sakash.bagdia@arm.com/**
689793Sakash.bagdia@arm.com * The ClockDomain provides clock to group of clocked objects bundled
699827Sakash.bagdia@arm.com * under the same clock domain. The clock domains, in turn, are
709827Sakash.bagdia@arm.com * grouped into voltage domains. The clock domains provide support for
719793Sakash.bagdia@arm.com * a hierarchial structure with source and derived domains.
729793Sakash.bagdia@arm.com */
739793Sakash.bagdia@arm.comclass ClockDomain : public SimObject
749793Sakash.bagdia@arm.com{
759793Sakash.bagdia@arm.com
7610021Sandreas.hansson@arm.com  private:
7710021Sandreas.hansson@arm.com
7810021Sandreas.hansson@arm.com    /**
7910021Sandreas.hansson@arm.com     * Stat to report clock period of clock domain
8010021Sandreas.hansson@arm.com     */
8110021Sandreas.hansson@arm.com    Stats::Value currentClock;
8210021Sandreas.hansson@arm.com
839793Sakash.bagdia@arm.com  protected:
849793Sakash.bagdia@arm.com
859793Sakash.bagdia@arm.com    /**
869793Sakash.bagdia@arm.com     * Pre-computed clock period in ticks. This is populated by the
879793Sakash.bagdia@arm.com     * inheriting classes based on how their period is determined.
889793Sakash.bagdia@arm.com     */
899793Sakash.bagdia@arm.com    Tick _clockPeriod;
909793Sakash.bagdia@arm.com
919793Sakash.bagdia@arm.com    /**
929827Sakash.bagdia@arm.com     * Voltage domain this clock domain belongs to
939827Sakash.bagdia@arm.com     */
949827Sakash.bagdia@arm.com    VoltageDomain *_voltageDomain;
959827Sakash.bagdia@arm.com
969827Sakash.bagdia@arm.com    /**
979793Sakash.bagdia@arm.com     * Pointers to potential derived clock domains so we can propagate
989793Sakash.bagdia@arm.com     * changes.
999793Sakash.bagdia@arm.com     */
1009793Sakash.bagdia@arm.com    std::vector<DerivedClockDomain*> children;
1019793Sakash.bagdia@arm.com
10210000Sclt67@cornell.edu    /**
10310000Sclt67@cornell.edu     * Pointers to members of this clock domain, so that when the clock
10410000Sclt67@cornell.edu     * period changes, we can update each member's tick.
10510000Sclt67@cornell.edu     */
10611009Sandreas.sandberg@arm.com    std::vector<Clocked *> members;
10710000Sclt67@cornell.edu
1089793Sakash.bagdia@arm.com  public:
1099793Sakash.bagdia@arm.com
1109793Sakash.bagdia@arm.com    typedef ClockDomainParams Params;
1119827Sakash.bagdia@arm.com    ClockDomain(const Params *p, VoltageDomain *voltage_domain) :
1129827Sakash.bagdia@arm.com        SimObject(p),
1139827Sakash.bagdia@arm.com        _clockPeriod(0),
1149827Sakash.bagdia@arm.com        _voltageDomain(voltage_domain) {}
1159793Sakash.bagdia@arm.com
11610021Sandreas.hansson@arm.com    void regStats();
11710021Sandreas.hansson@arm.com
1189793Sakash.bagdia@arm.com    /**
1199793Sakash.bagdia@arm.com     * Get the clock period.
1209793Sakash.bagdia@arm.com     *
1219793Sakash.bagdia@arm.com     * @return Clock period in ticks
1229793Sakash.bagdia@arm.com     */
12310249Sstephan.diestelhorst@arm.com    Tick clockPeriod() const { return _clockPeriod; }
1249793Sakash.bagdia@arm.com
1259793Sakash.bagdia@arm.com    /**
12611009Sandreas.sandberg@arm.com     * Register a Clocked object with this ClockDomain.
12710000Sclt67@cornell.edu     *
12811009Sandreas.sandberg@arm.com     * @param Clocked to add as a member
12910000Sclt67@cornell.edu     */
13011009Sandreas.sandberg@arm.com    void registerWithClockDomain(Clocked *c)
13110000Sclt67@cornell.edu    {
13210000Sclt67@cornell.edu        assert(c != NULL);
13310000Sclt67@cornell.edu        assert(std::find(members.begin(), members.end(), c) == members.end());
13410000Sclt67@cornell.edu        members.push_back(c);
13510000Sclt67@cornell.edu    }
13610000Sclt67@cornell.edu
13710000Sclt67@cornell.edu    /**
1389827Sakash.bagdia@arm.com     * Get the voltage domain.
1399827Sakash.bagdia@arm.com     *
1409827Sakash.bagdia@arm.com     * @return Voltage domain this clock domain belongs to
1419827Sakash.bagdia@arm.com     */
1429827Sakash.bagdia@arm.com    inline VoltageDomain *voltageDomain() const { return _voltageDomain; }
1439827Sakash.bagdia@arm.com
1449827Sakash.bagdia@arm.com
1459827Sakash.bagdia@arm.com    /**
1469827Sakash.bagdia@arm.com     * Get the current voltage this clock domain operates at.
1479827Sakash.bagdia@arm.com     *
1489827Sakash.bagdia@arm.com     * @return Voltage applied to the clock domain
1499827Sakash.bagdia@arm.com     */
15010249Sstephan.diestelhorst@arm.com    double voltage() const;
1519827Sakash.bagdia@arm.com
1529827Sakash.bagdia@arm.com    /**
1539793Sakash.bagdia@arm.com     * Add a derived domain.
1549793Sakash.bagdia@arm.com     *
1559793Sakash.bagdia@arm.com     * @param Derived domain to add as a child
1569793Sakash.bagdia@arm.com     */
1579793Sakash.bagdia@arm.com    void addDerivedDomain(DerivedClockDomain *clock_domain)
1589793Sakash.bagdia@arm.com    { children.push_back(clock_domain); }
1599793Sakash.bagdia@arm.com
1609793Sakash.bagdia@arm.com};
1619793Sakash.bagdia@arm.com
1629793Sakash.bagdia@arm.com/**
1639793Sakash.bagdia@arm.com * The source clock domains provides the notion of a clock domain that is
1649793Sakash.bagdia@arm.com * connected to a tunable clock source. It maintains the clock period and
16510249Sstephan.diestelhorst@arm.com * provides methods for setting/getting the clock and  configuration parameters
16610249Sstephan.diestelhorst@arm.com * for clock domain that handler is going to manage. This includes frequency
16710249Sstephan.diestelhorst@arm.com * values at various performance levels, domain id, and current performance
16810249Sstephan.diestelhorst@arm.com * level. Note that a performance level as requested by the software corresponds
16910249Sstephan.diestelhorst@arm.com * to one of the frequency operational points the domain can operate at.
1709793Sakash.bagdia@arm.com */
1719793Sakash.bagdia@arm.comclass SrcClockDomain : public ClockDomain
1729793Sakash.bagdia@arm.com{
1739793Sakash.bagdia@arm.com
1749793Sakash.bagdia@arm.com  public:
1759793Sakash.bagdia@arm.com
1769793Sakash.bagdia@arm.com    typedef SrcClockDomainParams Params;
1779793Sakash.bagdia@arm.com    SrcClockDomain(const Params *p);
1789793Sakash.bagdia@arm.com
1799793Sakash.bagdia@arm.com    /**
1809793Sakash.bagdia@arm.com     * Set new clock value
1819793Sakash.bagdia@arm.com     * @param clock The new clock period in ticks
1829793Sakash.bagdia@arm.com     */
1839793Sakash.bagdia@arm.com    void clockPeriod(Tick clock_period);
1849793Sakash.bagdia@arm.com
18510000Sclt67@cornell.edu    // Explicitly import the otherwise hidden clockPeriod
18610000Sclt67@cornell.edu    using ClockDomain::clockPeriod;
18710249Sstephan.diestelhorst@arm.com
18810249Sstephan.diestelhorst@arm.com    typedef int32_t DomainID;
18910249Sstephan.diestelhorst@arm.com    static const DomainID emptyDomainID = -1;
19010249Sstephan.diestelhorst@arm.com
19110249Sstephan.diestelhorst@arm.com    /**
19210249Sstephan.diestelhorst@arm.com     * @return the domainID of the domain
19310249Sstephan.diestelhorst@arm.com     */
19410249Sstephan.diestelhorst@arm.com    uint32_t domainID() const { return _domainID; }
19510249Sstephan.diestelhorst@arm.com
19610249Sstephan.diestelhorst@arm.com    typedef uint32_t PerfLevel;
19710249Sstephan.diestelhorst@arm.com    /**
19810249Sstephan.diestelhorst@arm.com     * Checks whether the performance level requested exists in the current
19910249Sstephan.diestelhorst@arm.com     * domain configuration
20010249Sstephan.diestelhorst@arm.com     *
20110249Sstephan.diestelhorst@arm.com     * @param the target performance level of the domain
20210249Sstephan.diestelhorst@arm.com     *
20310249Sstephan.diestelhorst@arm.com     * @return validity status of the given performance level
20410249Sstephan.diestelhorst@arm.com     */
20510249Sstephan.diestelhorst@arm.com    bool validPerfLevel(PerfLevel perf_level) const {
20610249Sstephan.diestelhorst@arm.com        return perf_level < numPerfLevels();
20710249Sstephan.diestelhorst@arm.com    }
20810249Sstephan.diestelhorst@arm.com
20910249Sstephan.diestelhorst@arm.com    /**
21010249Sstephan.diestelhorst@arm.com     * Sets the current performance level of the domain
21110249Sstephan.diestelhorst@arm.com     *
21210249Sstephan.diestelhorst@arm.com     * @param perf_level the target performance level
21310249Sstephan.diestelhorst@arm.com     */
21410249Sstephan.diestelhorst@arm.com    void perfLevel(PerfLevel perf_level);
21510249Sstephan.diestelhorst@arm.com
21610249Sstephan.diestelhorst@arm.com    /**
21710249Sstephan.diestelhorst@arm.com     * @return the current performance level of the domain
21810249Sstephan.diestelhorst@arm.com     */
21910249Sstephan.diestelhorst@arm.com    PerfLevel perfLevel() const { return _perfLevel; }
22010249Sstephan.diestelhorst@arm.com
22110249Sstephan.diestelhorst@arm.com    /**
22210249Sstephan.diestelhorst@arm.com     * Get the number of available performance levels for this clock domain.
22310249Sstephan.diestelhorst@arm.com     *
22410249Sstephan.diestelhorst@arm.com     * @return Number of perf levels configured for this domain.
22510249Sstephan.diestelhorst@arm.com     */
22610249Sstephan.diestelhorst@arm.com    PerfLevel numPerfLevels() const {return freqOpPoints.size();}
22710249Sstephan.diestelhorst@arm.com
22810249Sstephan.diestelhorst@arm.com    /**
22910249Sstephan.diestelhorst@arm.com     * @returns the clock period (expressed in ticks) for the current
23010249Sstephan.diestelhorst@arm.com     * performance level
23110249Sstephan.diestelhorst@arm.com     */
23210249Sstephan.diestelhorst@arm.com    Tick clkPeriodAtPerfLevel() const { return freqOpPoints[perfLevel()]; }
23310249Sstephan.diestelhorst@arm.com
23410249Sstephan.diestelhorst@arm.com    Tick clkPeriodAtPerfLevel(PerfLevel perf_level) const
23510249Sstephan.diestelhorst@arm.com    {
23610249Sstephan.diestelhorst@arm.com        assert(validPerfLevel(perf_level));
23710249Sstephan.diestelhorst@arm.com        return freqOpPoints[perf_level];
23810249Sstephan.diestelhorst@arm.com    }
23910249Sstephan.diestelhorst@arm.com
24011169Sandreas.hansson@arm.com    void startup() override;
24110905Sandreas.sandberg@arm.com
24211168Sandreas.hansson@arm.com    void serialize(CheckpointOut &cp) const override;
24311168Sandreas.hansson@arm.com    void unserialize(CheckpointIn &cp) override;
24410249Sstephan.diestelhorst@arm.com
24510249Sstephan.diestelhorst@arm.com  private:
24610249Sstephan.diestelhorst@arm.com    /**
24711416Ssascha.bischoff@ARM.com     * Inform other components about the changed performance level
24811416Ssascha.bischoff@ARM.com     */
24911416Ssascha.bischoff@ARM.com    void signalPerfLevelUpdate();
25011416Ssascha.bischoff@ARM.com
25111416Ssascha.bischoff@ARM.com    /**
25210249Sstephan.diestelhorst@arm.com      * List of possible frequency operational points, should be in
25310249Sstephan.diestelhorst@arm.com      * descending order
25410249Sstephan.diestelhorst@arm.com      * An empty list corresponds to default frequency specified for its
25510249Sstephan.diestelhorst@arm.com      * clock domain, overall implying NO DVFS
25610249Sstephan.diestelhorst@arm.com      */
25710249Sstephan.diestelhorst@arm.com    const std::vector<Tick> freqOpPoints;
25810249Sstephan.diestelhorst@arm.com
25910249Sstephan.diestelhorst@arm.com    /**
26010249Sstephan.diestelhorst@arm.com      * Software recognizable id number for the domain, should be unique for
26110249Sstephan.diestelhorst@arm.com      * each domain
26210249Sstephan.diestelhorst@arm.com      */
26310249Sstephan.diestelhorst@arm.com    const uint32_t _domainID;
26410249Sstephan.diestelhorst@arm.com
26510249Sstephan.diestelhorst@arm.com    /**
26610249Sstephan.diestelhorst@arm.com      * Current performance level the domain is set to.
26710249Sstephan.diestelhorst@arm.com      * The performance level corresponds to one selected frequency (and related
26810249Sstephan.diestelhorst@arm.com      * voltage) from the supplied list of frequencies, with perfLevel = 0 being
26910249Sstephan.diestelhorst@arm.com      * the fastest performance state.
27010249Sstephan.diestelhorst@arm.com      */
27110249Sstephan.diestelhorst@arm.com    PerfLevel _perfLevel;
2729793Sakash.bagdia@arm.com};
2739793Sakash.bagdia@arm.com
2749793Sakash.bagdia@arm.com/**
2759793Sakash.bagdia@arm.com * The derived clock domains provides the notion of a clock domain
2769793Sakash.bagdia@arm.com * that is connected to a parent clock domain that can either be a
2779793Sakash.bagdia@arm.com * source clock domain or a derived clock domain. It maintains the
2789793Sakash.bagdia@arm.com * clock divider and provides methods for getting the clock.
2799793Sakash.bagdia@arm.com */
2809793Sakash.bagdia@arm.comclass DerivedClockDomain: public ClockDomain
2819793Sakash.bagdia@arm.com{
2829793Sakash.bagdia@arm.com
2839793Sakash.bagdia@arm.com  public:
2849793Sakash.bagdia@arm.com
2859793Sakash.bagdia@arm.com    typedef DerivedClockDomainParams Params;
2869793Sakash.bagdia@arm.com    DerivedClockDomain(const Params *p);
2879793Sakash.bagdia@arm.com
2889793Sakash.bagdia@arm.com    /**
2899793Sakash.bagdia@arm.com     * Called by the parent clock domain to propagate changes. This
2909793Sakash.bagdia@arm.com     * also involves propagating the change further to any children of
2919793Sakash.bagdia@arm.com     * the derived domain itself.
2929793Sakash.bagdia@arm.com     */
2939793Sakash.bagdia@arm.com    void updateClockPeriod();
2949793Sakash.bagdia@arm.com
2959793Sakash.bagdia@arm.com  private:
2969793Sakash.bagdia@arm.com
2979793Sakash.bagdia@arm.com    /**
2989793Sakash.bagdia@arm.com     * Reference to the parent clock domain this clock domain derives
2999793Sakash.bagdia@arm.com     * its clock period from
3009793Sakash.bagdia@arm.com     */
3019793Sakash.bagdia@arm.com    ClockDomain &parent;
3029793Sakash.bagdia@arm.com
3039793Sakash.bagdia@arm.com    /**
3049793Sakash.bagdia@arm.com     * Local clock divider of the domain
3059793Sakash.bagdia@arm.com     */
3069793Sakash.bagdia@arm.com    const uint64_t clockDivider;
3079793Sakash.bagdia@arm.com};
3089793Sakash.bagdia@arm.com
3099793Sakash.bagdia@arm.com#endif
310