clock_domain.hh revision 10905
12810SN/A/*
210693SMarco.Balboni@ARM.com * Copyright (c) 2013-2014 ARM Limited
38856Sandreas.hansson@arm.com * Copyright (c) 2013 Cornell University
48856Sandreas.hansson@arm.com * All rights reserved
58856Sandreas.hansson@arm.com *
68856Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
78856Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
88856Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
98856Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
108856Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
118856Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
128856Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
138856Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
142810SN/A *
152810SN/A * Redistribution and use in source and binary forms, with or without
162810SN/A * modification, are permitted provided that the following conditions are
172810SN/A * met: redistributions of source code must retain the above copyright
182810SN/A * notice, this list of conditions and the following disclaimer;
192810SN/A * redistributions in binary form must reproduce the above copyright
202810SN/A * notice, this list of conditions and the following disclaimer in the
212810SN/A * documentation and/or other materials provided with the distribution;
222810SN/A * neither the name of the copyright holders nor the names of its
232810SN/A * contributors may be used to endorse or promote products derived from
242810SN/A * this software without specific prior written permission.
252810SN/A *
262810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
272810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
282810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
292810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
332810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
342810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
352810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
362810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
372810SN/A *
382810SN/A * Authors: Vasileios Spiliopoulos
392810SN/A *          Akash Bagdia
402810SN/A *          Christopher Torng
414458SN/A *          Stephan Diestelhorst
424458SN/A */
432810SN/A
442810SN/A/**
452810SN/A * @file
462810SN/A * ClockDomain declarations.
472810SN/A */
482810SN/A
492810SN/A#ifndef __SIM_CLOCK_DOMAIN_HH__
502810SN/A#define __SIM_CLOCK_DOMAIN_HH__
512810SN/A
522810SN/A#include <algorithm>
537676Snate@binkert.org
547676Snate@binkert.org#include "base/statistics.hh"
557676Snate@binkert.org#include "params/ClockDomain.hh"
562810SN/A#include "params/DerivedClockDomain.hh"
572810SN/A#include "params/SrcClockDomain.hh"
582825SN/A#include "sim/sim_object.hh"
592810SN/A
602810SN/A/**
616215Snate@binkert.org * Forward declaration
628232Snate@binkert.org */
638232Snate@binkert.orgclass DerivedClockDomain;
645338Sstever@gmail.comclass VoltageDomain;
652810SN/Aclass ClockedObject;
662810SN/A
678914Sandreas.hansson@arm.com/**
688229Snate@binkert.org * The ClockDomain provides clock to group of clocked objects bundled
695034SN/A * under the same clock domain. The clock domains, in turn, are
702811SN/A * grouped into voltage domains. The clock domains provide support for
718786Sgblack@eecs.umich.edu * a hierarchial structure with source and derived domains.
724626SN/A */
738833Sdam.sunwoo@arm.comclass ClockDomain : public SimObject
742810SN/A{
753194SN/A
762810SN/A  private:
772810SN/A
782810SN/A    /**
792810SN/A     * Stat to report clock period of clock domain
802810SN/A     */
814628SN/A    Stats::Value currentClock;
824628SN/A
834628SN/A  protected:
844628SN/A
854628SN/A    /**
864628SN/A     * Pre-computed clock period in ticks. This is populated by the
874628SN/A     * inheriting classes based on how their period is determined.
884628SN/A     */
898737Skoansin.tan@gmail.com    Tick _clockPeriod;
904628SN/A
914628SN/A    /**
924628SN/A     * Voltage domain this clock domain belongs to
934628SN/A     */
944628SN/A    VoltageDomain *_voltageDomain;
954628SN/A
964628SN/A    /**
974628SN/A     * Pointers to potential derived clock domains so we can propagate
984628SN/A     * changes.
994628SN/A     */
1004628SN/A    std::vector<DerivedClockDomain*> children;
1014628SN/A
1024628SN/A    /**
1034628SN/A     * Pointers to members of this clock domain, so that when the clock
1044628SN/A     * period changes, we can update each member's tick.
1054628SN/A     */
1064628SN/A    std::vector<ClockedObject*> members;
1074628SN/A
1084628SN/A  public:
1094628SN/A
1108737Skoansin.tan@gmail.com    typedef ClockDomainParams Params;
1114628SN/A    ClockDomain(const Params *p, VoltageDomain *voltage_domain) :
1128856Sandreas.hansson@arm.com        SimObject(p),
1138856Sandreas.hansson@arm.com        _clockPeriod(0),
1148856Sandreas.hansson@arm.com        _voltageDomain(voltage_domain) {}
1158856Sandreas.hansson@arm.com
1168856Sandreas.hansson@arm.com    void regStats();
1178856Sandreas.hansson@arm.com
1188856Sandreas.hansson@arm.com    /**
1198856Sandreas.hansson@arm.com     * Get the clock period.
1208856Sandreas.hansson@arm.com     *
1218922Swilliam.wang@arm.com     * @return Clock period in ticks
1222810SN/A     */
1238856Sandreas.hansson@arm.com    Tick clockPeriod() const { return _clockPeriod; }
1242844SN/A
1258856Sandreas.hansson@arm.com    /**
1268856Sandreas.hansson@arm.com     * Register a ClockedObject to this ClockDomain.
1278856Sandreas.hansson@arm.com     *
1288856Sandreas.hansson@arm.com     * @param ClockedObject to add as a member
1298856Sandreas.hansson@arm.com     */
1308856Sandreas.hansson@arm.com    void registerWithClockDomain(ClockedObject *c)
1318856Sandreas.hansson@arm.com    {
1328856Sandreas.hansson@arm.com        assert(c != NULL);
1338856Sandreas.hansson@arm.com        assert(std::find(members.begin(), members.end(), c) == members.end());
1348914Sandreas.hansson@arm.com        members.push_back(c);
1358856Sandreas.hansson@arm.com    }
1368856Sandreas.hansson@arm.com
1373738SN/A    /**
1384458SN/A     * Get the voltage domain.
1398856Sandreas.hansson@arm.com     *
1408975Sandreas.hansson@arm.com     * @return Voltage domain this clock domain belongs to
1418922Swilliam.wang@arm.com     */
1428914Sandreas.hansson@arm.com    inline VoltageDomain *voltageDomain() const { return _voltageDomain; }
1432810SN/A
1448856Sandreas.hansson@arm.com
1458856Sandreas.hansson@arm.com    /**
1468856Sandreas.hansson@arm.com     * Get the current voltage this clock domain operates at.
1478914Sandreas.hansson@arm.com     *
1488856Sandreas.hansson@arm.com     * @return Voltage applied to the clock domain
1498922Swilliam.wang@arm.com     */
1508856Sandreas.hansson@arm.com    double voltage() const;
1513013SN/A
1528856Sandreas.hansson@arm.com    /**
1538856Sandreas.hansson@arm.com     * Add a derived domain.
1548856Sandreas.hansson@arm.com     *
1558856Sandreas.hansson@arm.com     * @param Derived domain to add as a child
1568856Sandreas.hansson@arm.com     */
1578856Sandreas.hansson@arm.com    void addDerivedDomain(DerivedClockDomain *clock_domain)
1588856Sandreas.hansson@arm.com    { children.push_back(clock_domain); }
1598856Sandreas.hansson@arm.com
1608922Swilliam.wang@arm.com};
1618856Sandreas.hansson@arm.com
1625314SN/A/**
1632811SN/A * The source clock domains provides the notion of a clock domain that is
1648856Sandreas.hansson@arm.com * connected to a tunable clock source. It maintains the clock period and
1658856Sandreas.hansson@arm.com * provides methods for setting/getting the clock and  configuration parameters
1662810SN/A * for clock domain that handler is going to manage. This includes frequency
1672810SN/A * values at various performance levels, domain id, and current performance
1688856Sandreas.hansson@arm.com * level. Note that a performance level as requested by the software corresponds
1692810SN/A * to one of the frequency operational points the domain can operate at.
1702810SN/A */
17110345SCurtis.Dunham@arm.comclass SrcClockDomain : public ClockDomain
17210345SCurtis.Dunham@arm.com{
1738856Sandreas.hansson@arm.com
1748856Sandreas.hansson@arm.com  public:
1758856Sandreas.hansson@arm.com
1768856Sandreas.hansson@arm.com    typedef SrcClockDomainParams Params;
1773606SN/A    SrcClockDomain(const Params *p);
1788914Sandreas.hansson@arm.com
1798975Sandreas.hansson@arm.com    /**
1808914Sandreas.hansson@arm.com     * Set new clock value
1812810SN/A     * @param clock The new clock period in ticks
1822810SN/A     */
1832897SN/A    void clockPeriod(Tick clock_period);
1842897SN/A
1858856Sandreas.hansson@arm.com    // Explicitly import the otherwise hidden clockPeriod
1864458SN/A    using ClockDomain::clockPeriod;
18710344Sandreas.hansson@arm.com
18810344Sandreas.hansson@arm.com    typedef int32_t DomainID;
18910344Sandreas.hansson@arm.com    static const DomainID emptyDomainID = -1;
19010344Sandreas.hansson@arm.com
1918856Sandreas.hansson@arm.com    /**
1922811SN/A     * @return the domainID of the domain
1932810SN/A     */
1948856Sandreas.hansson@arm.com    uint32_t domainID() const { return _domainID; }
1958856Sandreas.hansson@arm.com
1963338SN/A    typedef uint32_t PerfLevel;
1974626SN/A    /**
1984626SN/A     * Checks whether the performance level requested exists in the current
1994626SN/A     * domain configuration
2004626SN/A     *
2014626SN/A     * @param the target performance level of the domain
2024626SN/A     *
2034626SN/A     * @return validity status of the given performance level
2044626SN/A     */
20510693SMarco.Balboni@ARM.com    bool validPerfLevel(PerfLevel perf_level) const {
20610693SMarco.Balboni@ARM.com        return perf_level < numPerfLevels();
20710693SMarco.Balboni@ARM.com    }
20810693SMarco.Balboni@ARM.com
20910693SMarco.Balboni@ARM.com    /**
21010693SMarco.Balboni@ARM.com     * Sets the current performance level of the domain
21110693SMarco.Balboni@ARM.com     *
21210693SMarco.Balboni@ARM.com     * @param perf_level the target performance level
21310693SMarco.Balboni@ARM.com     */
21410693SMarco.Balboni@ARM.com    void perfLevel(PerfLevel perf_level);
21510693SMarco.Balboni@ARM.com
2164628SN/A    /**
2174628SN/A     * @return the current performance level of the domain
2184628SN/A     */
2194666SN/A    PerfLevel perfLevel() const { return _perfLevel; }
2204628SN/A
2214628SN/A    /**
2224628SN/A     * Get the number of available performance levels for this clock domain.
2234628SN/A     *
2244628SN/A     * @return Number of perf levels configured for this domain.
2254628SN/A     */
2264628SN/A    PerfLevel numPerfLevels() const {return freqOpPoints.size();}
2274628SN/A
2284628SN/A    /**
2294628SN/A     * @returns the clock period (expressed in ticks) for the current
2304628SN/A     * performance level
2314628SN/A     */
23210679Sandreas.hansson@arm.com    Tick clkPeriodAtPerfLevel() const { return freqOpPoints[perfLevel()]; }
2334628SN/A
2344628SN/A    Tick clkPeriodAtPerfLevel(PerfLevel perf_level) const
2354628SN/A    {
23610679Sandreas.hansson@arm.com        assert(validPerfLevel(perf_level));
2374628SN/A        return freqOpPoints[perf_level];
2384628SN/A    }
2394628SN/A
2404628SN/A    void startup();
2414628SN/A
2429347SAndreas.Sandberg@arm.com    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
2439347SAndreas.Sandberg@arm.com    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
2449347SAndreas.Sandberg@arm.com
2459347SAndreas.Sandberg@arm.com  private:
2469347SAndreas.Sandberg@arm.com    /**
2479347SAndreas.Sandberg@arm.com      * List of possible frequency operational points, should be in
2489347SAndreas.Sandberg@arm.com      * descending order
2499347SAndreas.Sandberg@arm.com      * An empty list corresponds to default frequency specified for its
2509347SAndreas.Sandberg@arm.com      * clock domain, overall implying NO DVFS
2519347SAndreas.Sandberg@arm.com      */
2529347SAndreas.Sandberg@arm.com    const std::vector<Tick> freqOpPoints;
2539347SAndreas.Sandberg@arm.com
2549347SAndreas.Sandberg@arm.com    /**
2559347SAndreas.Sandberg@arm.com      * Software recognizable id number for the domain, should be unique for
2569347SAndreas.Sandberg@arm.com      * each domain
2579347SAndreas.Sandberg@arm.com      */
2589347SAndreas.Sandberg@arm.com    const uint32_t _domainID;
2599347SAndreas.Sandberg@arm.com
2609347SAndreas.Sandberg@arm.com    /**
2614626SN/A      * Current performance level the domain is set to.
2626227Snate@binkert.org      * The performance level corresponds to one selected frequency (and related
2634626SN/A      * voltage) from the supplied list of frequencies, with perfLevel = 0 being
2644630SN/A      * the fastest performance state.
26510693SMarco.Balboni@ARM.com      */
26610693SMarco.Balboni@ARM.com    PerfLevel _perfLevel;
2674630SN/A};
26810693SMarco.Balboni@ARM.com
2699263Smrinmoy.ghosh@arm.com/**
2709263Smrinmoy.ghosh@arm.com * The derived clock domains provides the notion of a clock domain
27110693SMarco.Balboni@ARM.com * that is connected to a parent clock domain that can either be a
27210693SMarco.Balboni@ARM.com * source clock domain or a derived clock domain. It maintains the
27310693SMarco.Balboni@ARM.com * clock divider and provides methods for getting the clock.
27410693SMarco.Balboni@ARM.com */
27510693SMarco.Balboni@ARM.comclass DerivedClockDomain: public ClockDomain
27610693SMarco.Balboni@ARM.com{
27710693SMarco.Balboni@ARM.com
27810693SMarco.Balboni@ARM.com  public:
27910693SMarco.Balboni@ARM.com
28010693SMarco.Balboni@ARM.com    typedef DerivedClockDomainParams Params;
28110693SMarco.Balboni@ARM.com    DerivedClockDomain(const Params *p);
28210693SMarco.Balboni@ARM.com
28310693SMarco.Balboni@ARM.com    /**
2849263Smrinmoy.ghosh@arm.com     * Called by the parent clock domain to propagate changes. This
2859288Sandreas.hansson@arm.com     * also involves propagating the change further to any children of
2864630SN/A     * the derived domain itself.
2874626SN/A     */
2884626SN/A    void updateClockPeriod();
2894626SN/A
2906122SSteve.Reinhardt@amd.com  private:
2919529Sandreas.hansson@arm.com
2924626SN/A    /**
2938134SAli.Saidi@ARM.com     * Reference to the parent clock domain this clock domain derives
2948134SAli.Saidi@ARM.com     * its clock period from
2958134SAli.Saidi@ARM.com     */
2969529Sandreas.hansson@arm.com    ClockDomain &parent;
2978134SAli.Saidi@ARM.com
2982810SN/A    /**
2992810SN/A     * Local clock divider of the domain
3002810SN/A     */
3012810SN/A    const uint64_t clockDivider;
3022810SN/A};
3032810SN/A
3046122SSteve.Reinhardt@amd.com#endif
3056122SSteve.Reinhardt@amd.com