clocked_object.hh revision 11524:3101ce98c55c
15625Sgblack@eecs.umich.edu/* 25625Sgblack@eecs.umich.edu * Copyright (c) 2012-2013, 2015-2016 ARM Limited 35625Sgblack@eecs.umich.edu * Copyright (c) 2013 Cornell University 45625Sgblack@eecs.umich.edu * All rights reserved 57087Snate@binkert.org * 67087Snate@binkert.org * The license below extends only to copyright in the software and shall 77087Snate@binkert.org * not be construed as granting a license to any other intellectual 87087Snate@binkert.org * property including but not limited to intellectual property relating 97087Snate@binkert.org * to a hardware implementation of the functionality of the software 107087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 117087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 127087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 135625Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 147087Snate@binkert.org * 157087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 167087Snate@binkert.org * modification, are permitted provided that the following conditions are 177087Snate@binkert.org * met: redistributions of source code must retain the above copyright 187087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 197087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 207087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 217087Snate@binkert.org * documentation and/or other materials provided with the distribution; 225625Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 237087Snate@binkert.org * contributors may be used to endorse or promote products derived from 245625Sgblack@eecs.umich.edu * this software without specific prior written permission. 255625Sgblack@eecs.umich.edu * 265625Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 275625Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 285625Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 295625Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 305625Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 315625Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 325625Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 335625Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 345625Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 355625Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 365625Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 375625Sgblack@eecs.umich.edu * 385625Sgblack@eecs.umich.edu * Authors: Andreas Hansson 395625Sgblack@eecs.umich.edu * Christopher Torng 405625Sgblack@eecs.umich.edu * Akash Bagdia 415625Sgblack@eecs.umich.edu * David Guillen Fandos 425625Sgblack@eecs.umich.edu */ 435625Sgblack@eecs.umich.edu 445625Sgblack@eecs.umich.edu/** 455625Sgblack@eecs.umich.edu * @file 465625Sgblack@eecs.umich.edu * ClockedObject declaration and implementation. 475625Sgblack@eecs.umich.edu */ 485625Sgblack@eecs.umich.edu 495625Sgblack@eecs.umich.edu#ifndef __SIM_CLOCKED_OBJECT_HH__ 505625Sgblack@eecs.umich.edu#define __SIM_CLOCKED_OBJECT_HH__ 515625Sgblack@eecs.umich.edu 528229Snate@binkert.org#include "base/callback.hh" 535625Sgblack@eecs.umich.edu#include "base/intmath.hh" 548706Sandreas.hansson@arm.com#include "base/misc.hh" 555625Sgblack@eecs.umich.edu#include "enums/PwrState.hh" 565625Sgblack@eecs.umich.edu#include "params/ClockedObject.hh" 578737Skoansin.tan@gmail.com#include "sim/core.hh" 588737Skoansin.tan@gmail.com#include "sim/clock_domain.hh" 595625Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 605625Sgblack@eecs.umich.edu 618737Skoansin.tan@gmail.com/** 628737Skoansin.tan@gmail.com * Helper class for objects that need to be clocked. Clocked objects 635625Sgblack@eecs.umich.edu * typically inherit from this class. Objects that need SimObject 645625Sgblack@eecs.umich.edu * functionality as well should inherit from ClockedObject. 658737Skoansin.tan@gmail.com */ 668737Skoansin.tan@gmail.comclass Clocked 678737Skoansin.tan@gmail.com{ 688737Skoansin.tan@gmail.com 698737Skoansin.tan@gmail.com private: 705625Sgblack@eecs.umich.edu // the tick value of the next clock edge (>= curTick()) at the 715625Sgblack@eecs.umich.edu // time of the last call to update() 728737Skoansin.tan@gmail.com mutable Tick tick; 738737Skoansin.tan@gmail.com 748737Skoansin.tan@gmail.com // The cycle counter value corresponding to the current value of 755625Sgblack@eecs.umich.edu // 'tick' 765625Sgblack@eecs.umich.edu mutable Cycles cycle; 775625Sgblack@eecs.umich.edu 785625Sgblack@eecs.umich.edu /** 795625Sgblack@eecs.umich.edu * Align cycle and tick to the next clock edge if not already done. When 805625Sgblack@eecs.umich.edu * complete, tick must be at least curTick(). 815625Sgblack@eecs.umich.edu */ 825625Sgblack@eecs.umich.edu void update() const 835625Sgblack@eecs.umich.edu { 845625Sgblack@eecs.umich.edu // both tick and cycle are up-to-date and we are done, note 855625Sgblack@eecs.umich.edu // that the >= is important as it captures cases where tick 865625Sgblack@eecs.umich.edu // has already passed curTick() 875625Sgblack@eecs.umich.edu if (tick >= curTick()) 885625Sgblack@eecs.umich.edu return; 895625Sgblack@eecs.umich.edu 905625Sgblack@eecs.umich.edu // optimise for the common case and see if the tick should be 915625Sgblack@eecs.umich.edu // advanced by a single clock period 925625Sgblack@eecs.umich.edu tick += clockPeriod(); 935625Sgblack@eecs.umich.edu ++cycle; 945625Sgblack@eecs.umich.edu 955625Sgblack@eecs.umich.edu // see if we are done at this point 968706Sandreas.hansson@arm.com if (tick >= curTick()) 975625Sgblack@eecs.umich.edu return; 985625Sgblack@eecs.umich.edu 995625Sgblack@eecs.umich.edu // if not, we have to recalculate the cycle and tick, we 1005625Sgblack@eecs.umich.edu // perform the calculations in terms of relative cycles to 1015625Sgblack@eecs.umich.edu // allow changes to the clock period in the future 1025625Sgblack@eecs.umich.edu Cycles elapsedCycles(divCeil(curTick() - tick, clockPeriod())); 1035625Sgblack@eecs.umich.edu cycle += elapsedCycles; 1045625Sgblack@eecs.umich.edu tick += elapsedCycles * clockPeriod(); 1055625Sgblack@eecs.umich.edu } 1065625Sgblack@eecs.umich.edu 1075625Sgblack@eecs.umich.edu /** 1085625Sgblack@eecs.umich.edu * The clock domain this clocked object belongs to 1095625Sgblack@eecs.umich.edu */ 1105625Sgblack@eecs.umich.edu ClockDomain &clockDomain; 1115625Sgblack@eecs.umich.edu 1125625Sgblack@eecs.umich.edu protected: 1135625Sgblack@eecs.umich.edu 1145625Sgblack@eecs.umich.edu /** 1155625Sgblack@eecs.umich.edu * Create a clocked object and set the clock domain based on the 1165625Sgblack@eecs.umich.edu * parameters. 1175625Sgblack@eecs.umich.edu */ 1185625Sgblack@eecs.umich.edu Clocked(ClockDomain &clk_domain) 1195625Sgblack@eecs.umich.edu : tick(0), cycle(0), clockDomain(clk_domain) 1208706Sandreas.hansson@arm.com { 1215625Sgblack@eecs.umich.edu // Register with the clock domain, so that if the clock domain 1225625Sgblack@eecs.umich.edu // frequency changes, we can update this object's tick. 1235625Sgblack@eecs.umich.edu clockDomain.registerWithClockDomain(this); 1245625Sgblack@eecs.umich.edu } 1255625Sgblack@eecs.umich.edu 1265625Sgblack@eecs.umich.edu Clocked(Clocked &) = delete; 1275625Sgblack@eecs.umich.edu Clocked &operator=(Clocked &) = delete; 1285625Sgblack@eecs.umich.edu 1295625Sgblack@eecs.umich.edu /** 1305625Sgblack@eecs.umich.edu * Virtual destructor due to inheritance. 1315625Sgblack@eecs.umich.edu */ 1325625Sgblack@eecs.umich.edu virtual ~Clocked() { } 1335625Sgblack@eecs.umich.edu 1345625Sgblack@eecs.umich.edu /** 1358706Sandreas.hansson@arm.com * Reset the object's clock using the current global tick value. Likely 1365625Sgblack@eecs.umich.edu * to be used only when the global clock is reset. Currently, this done 1375625Sgblack@eecs.umich.edu * only when Ruby is done warming up the memory system. 1385625Sgblack@eecs.umich.edu */ 1395625Sgblack@eecs.umich.edu void resetClock() const 1405625Sgblack@eecs.umich.edu { 1415625Sgblack@eecs.umich.edu Cycles elapsedCycles(divCeil(curTick(), clockPeriod())); 1425625Sgblack@eecs.umich.edu cycle = elapsedCycles; 1435625Sgblack@eecs.umich.edu tick = elapsedCycles * clockPeriod(); 1445625Sgblack@eecs.umich.edu } 1455625Sgblack@eecs.umich.edu 1465625Sgblack@eecs.umich.edu public: 1475625Sgblack@eecs.umich.edu 1485625Sgblack@eecs.umich.edu /** 1495625Sgblack@eecs.umich.edu * Update the tick to the current tick. 1505625Sgblack@eecs.umich.edu * 1515625Sgblack@eecs.umich.edu */ 1525625Sgblack@eecs.umich.edu inline void updateClockPeriod() const 1535625Sgblack@eecs.umich.edu { 1545625Sgblack@eecs.umich.edu update(); 1555625Sgblack@eecs.umich.edu } 1565625Sgblack@eecs.umich.edu 1575625Sgblack@eecs.umich.edu /** 1588706Sandreas.hansson@arm.com * Determine the tick when a cycle begins, by default the current one, but 1595625Sgblack@eecs.umich.edu * the argument also enables the caller to determine a future cycle. When 1605625Sgblack@eecs.umich.edu * curTick() is on a clock edge, the number of cycles in the parameter is 1615625Sgblack@eecs.umich.edu * added to curTick() to be returned. When curTick() is not aligned to a 1625625Sgblack@eecs.umich.edu * clock edge, the number of cycles in the parameter is added to the next 1635625Sgblack@eecs.umich.edu * clock edge. 1645625Sgblack@eecs.umich.edu * 1655625Sgblack@eecs.umich.edu * @param cycles The number of cycles into the future 1665625Sgblack@eecs.umich.edu * 1675625Sgblack@eecs.umich.edu * @return The start tick when the requested clock edge occurs. Precisely, 1685625Sgblack@eecs.umich.edu * this tick can be 1695625Sgblack@eecs.umich.edu * curTick() + [0, clockPeriod()) + clockPeriod() * cycles 1705625Sgblack@eecs.umich.edu */ 1715625Sgblack@eecs.umich.edu inline Tick clockEdge(Cycles cycles = Cycles(0)) const 1725625Sgblack@eecs.umich.edu { 1735625Sgblack@eecs.umich.edu // align tick to the next clock edge 1745625Sgblack@eecs.umich.edu update(); 1758706Sandreas.hansson@arm.com 1765625Sgblack@eecs.umich.edu // figure out when this future cycle is 1775625Sgblack@eecs.umich.edu return tick + clockPeriod() * cycles; 1785625Sgblack@eecs.umich.edu } 1795625Sgblack@eecs.umich.edu 1805625Sgblack@eecs.umich.edu /** 1815625Sgblack@eecs.umich.edu * Determine the current cycle, corresponding to a tick aligned to 1825625Sgblack@eecs.umich.edu * a clock edge. 1835625Sgblack@eecs.umich.edu * 1845625Sgblack@eecs.umich.edu * @return When curTick() is on a clock edge, return the Cycle corresponding 1855625Sgblack@eecs.umich.edu * to that clock edge. When curTick() is not on a clock edge, return the 1865625Sgblack@eecs.umich.edu * Cycle corresponding to the next clock edge. 1875625Sgblack@eecs.umich.edu */ 1885625Sgblack@eecs.umich.edu inline Cycles curCycle() const 1898706Sandreas.hansson@arm.com { 1905625Sgblack@eecs.umich.edu // align cycle to the next clock edge. 1915625Sgblack@eecs.umich.edu update(); 1925625Sgblack@eecs.umich.edu 1935625Sgblack@eecs.umich.edu return cycle; 1945625Sgblack@eecs.umich.edu } 1955625Sgblack@eecs.umich.edu 1965625Sgblack@eecs.umich.edu /** 1975625Sgblack@eecs.umich.edu * Based on the clock of the object, determine the start tick of the first 1985625Sgblack@eecs.umich.edu * cycle that is at least one cycle in the future. When curTick() is at the 1995625Sgblack@eecs.umich.edu * current cycle edge, this returns the next clock edge. When calling this 2005625Sgblack@eecs.umich.edu * during the middle of a cycle, this returns 2 clock edges in the future. 2015625Sgblack@eecs.umich.edu * 2025625Sgblack@eecs.umich.edu * @return The start tick of the first cycle that is at least one cycle in 2035625Sgblack@eecs.umich.edu * the future. Precisely, the returned tick can be in the range 2045625Sgblack@eecs.umich.edu * curTick() + [clockPeriod(), 2 * clockPeriod()) 2058706Sandreas.hansson@arm.com */ 2065625Sgblack@eecs.umich.edu Tick nextCycle() const 2075625Sgblack@eecs.umich.edu { return clockEdge(Cycles(1)); } 2085625Sgblack@eecs.umich.edu 2095625Sgblack@eecs.umich.edu inline uint64_t frequency() const 2105625Sgblack@eecs.umich.edu { 2115625Sgblack@eecs.umich.edu return SimClock::Frequency / clockPeriod(); 2125625Sgblack@eecs.umich.edu } 2135625Sgblack@eecs.umich.edu 2145625Sgblack@eecs.umich.edu inline Tick clockPeriod() const 2155625Sgblack@eecs.umich.edu { 2165625Sgblack@eecs.umich.edu return clockDomain.clockPeriod(); 2175625Sgblack@eecs.umich.edu } 2185625Sgblack@eecs.umich.edu 2195625Sgblack@eecs.umich.edu inline double voltage() const 2205625Sgblack@eecs.umich.edu { 2215625Sgblack@eecs.umich.edu return clockDomain.voltage(); 2225625Sgblack@eecs.umich.edu } 2235625Sgblack@eecs.umich.edu 2248706Sandreas.hansson@arm.com inline Cycles ticksToCycles(Tick t) const 2255625Sgblack@eecs.umich.edu { return Cycles(divCeil(t, clockPeriod())); } 2265625Sgblack@eecs.umich.edu 2275625Sgblack@eecs.umich.edu inline Tick cyclesToTicks(Cycles c) const 2285625Sgblack@eecs.umich.edu { return clockPeriod() * c; } 2295625Sgblack@eecs.umich.edu}; 2305625Sgblack@eecs.umich.edu 2315625Sgblack@eecs.umich.edu/** 2325625Sgblack@eecs.umich.edu * The ClockedObject class extends the SimObject with a clock and 2335625Sgblack@eecs.umich.edu * accessor functions to relate ticks to the cycles of the object. 2345625Sgblack@eecs.umich.edu */ 2355625Sgblack@eecs.umich.educlass ClockedObject 2365625Sgblack@eecs.umich.edu : public SimObject, public Clocked 2375625Sgblack@eecs.umich.edu{ 2385625Sgblack@eecs.umich.edu public: 2395625Sgblack@eecs.umich.edu ClockedObject(const ClockedObjectParams *p) 2405625Sgblack@eecs.umich.edu : SimObject(p), Clocked(*p->clk_domain), 2415625Sgblack@eecs.umich.edu _currPwrState(p->default_p_state), 2425625Sgblack@eecs.umich.edu prvEvalTick(0) 2435625Sgblack@eecs.umich.edu { } 2445625Sgblack@eecs.umich.edu 2455625Sgblack@eecs.umich.edu /** Parameters of ClockedObject */ 2465625Sgblack@eecs.umich.edu typedef ClockedObjectParams Params; 2475625Sgblack@eecs.umich.edu const Params* params() const 2485625Sgblack@eecs.umich.edu { return reinterpret_cast<const Params*>(_params); } 2495625Sgblack@eecs.umich.edu 2505625Sgblack@eecs.umich.edu void serialize(CheckpointOut &cp) const override; 2515625Sgblack@eecs.umich.edu void unserialize(CheckpointIn &cp) override; 2525625Sgblack@eecs.umich.edu 2535625Sgblack@eecs.umich.edu inline Enums::PwrState pwrState() const 2545625Sgblack@eecs.umich.edu { return _currPwrState; } 2555625Sgblack@eecs.umich.edu 2565625Sgblack@eecs.umich.edu inline std::string pwrStateName() const 2575625Sgblack@eecs.umich.edu { return Enums::PwrStateStrings[_currPwrState]; } 2585625Sgblack@eecs.umich.edu 2595625Sgblack@eecs.umich.edu /** Returns the percentage residency for each power state */ 2605625Sgblack@eecs.umich.edu std::vector<double> pwrStateWeights() const; 2615625Sgblack@eecs.umich.edu 2625625Sgblack@eecs.umich.edu /** 2635625Sgblack@eecs.umich.edu * Record stats values like state residency by computing the time 2645625Sgblack@eecs.umich.edu * difference from previous update. Also, updates the previous evaluation 2655625Sgblack@eecs.umich.edu * tick once all stats are recorded. 2665625Sgblack@eecs.umich.edu * Usually called on power state change and stats dump callback. 2675625Sgblack@eecs.umich.edu */ 2685625Sgblack@eecs.umich.edu void computeStats(); 2695625Sgblack@eecs.umich.edu 2705625Sgblack@eecs.umich.edu void pwrState(Enums::PwrState); 2715625Sgblack@eecs.umich.edu void regStats(); 2728706Sandreas.hansson@arm.com 2735625Sgblack@eecs.umich.edu protected: 2745625Sgblack@eecs.umich.edu 2755625Sgblack@eecs.umich.edu /** To keep track of the current power state */ 2765625Sgblack@eecs.umich.edu Enums::PwrState _currPwrState; 2775625Sgblack@eecs.umich.edu 2785625Sgblack@eecs.umich.edu Tick prvEvalTick; 2795625Sgblack@eecs.umich.edu 2805625Sgblack@eecs.umich.edu Stats::Scalar numPwrStateTransitions; 2815625Sgblack@eecs.umich.edu Stats::Distribution pwrStateClkGateDist; 2825625Sgblack@eecs.umich.edu Stats::Vector pwrStateResidencyTicks; 2835625Sgblack@eecs.umich.edu 2845625Sgblack@eecs.umich.edu}; 2855625Sgblack@eecs.umich.edu 2865625Sgblack@eecs.umich.educlass ClockedObjectDumpCallback : public Callback 2878706Sandreas.hansson@arm.com{ 2885625Sgblack@eecs.umich.edu ClockedObject *co; 2895625Sgblack@eecs.umich.edu public: 2905625Sgblack@eecs.umich.edu ClockedObjectDumpCallback(ClockedObject *co_t) : co(co_t) {} 2915625Sgblack@eecs.umich.edu virtual void process() { co->computeStats(); }; 2925625Sgblack@eecs.umich.edu}; 2935625Sgblack@eecs.umich.edu 2945625Sgblack@eecs.umich.edu#endif //__SIM_CLOCKED_OBJECT_HH__ 2955625Sgblack@eecs.umich.edu