clocked_object.hh revision 9296
16145SN/A/* 26145SN/A * Copyright (c) 2012 ARM Limited 36145SN/A * All rights reserved 46145SN/A * 56145SN/A * The license below extends only to copyright in the software and shall 66145SN/A * not be construed as granting a license to any other intellectual 76145SN/A * property including but not limited to intellectual property relating 86145SN/A * to a hardware implementation of the functionality of the software 96145SN/A * licensed hereunder. You may use the software subject to the license 106145SN/A * terms below provided that you ensure that this notice is replicated 116145SN/A * unmodified and in its entirety in all distributions of the software, 126145SN/A * modified or unmodified, in source code or in binary form. 136145SN/A * 146145SN/A * Redistribution and use in source and binary forms, with or without 156145SN/A * modification, are permitted provided that the following conditions are 166145SN/A * met: redistributions of source code must retain the above copyright 176145SN/A * notice, this list of conditions and the following disclaimer; 186145SN/A * redistributions in binary form must reproduce the above copyright 196145SN/A * notice, this list of conditions and the following disclaimer in the 206145SN/A * documentation and/or other materials provided with the distribution; 216145SN/A * neither the name of the copyright holders nor the names of its 226145SN/A * contributors may be used to endorse or promote products derived from 236145SN/A * this software without specific prior written permission. 246145SN/A * 256145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297832SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307832SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 319356Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 328232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337054SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 348257SBrad.Beckmann@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 358255SBrad.Beckmann@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367054SN/A * 376145SN/A * Authors: Andreas Hansson 387055SN/A */ 397055SN/A 407054SN/A/** 418257SBrad.Beckmann@amd.com * @file 426145SN/A * ClockedObject declaration and implementation. 436145SN/A */ 446145SN/A 456145SN/A#ifndef __SIM_CLOCKED_OBJECT_HH__ 466145SN/A#define __SIM_CLOCKED_OBJECT_HH__ 476145SN/A 486145SN/A#include "base/intmath.hh" 4911096Snilay@cs.wisc.edu#include "params/ClockedObject.hh" 5011096Snilay@cs.wisc.edu#include "sim/sim_object.hh" 5111096Snilay@cs.wisc.edu 5211096Snilay@cs.wisc.edu/** 5311096Snilay@cs.wisc.edu * The ClockedObject class extends the SimObject with a clock and 546145SN/A * accessor functions to relate ticks to the cycles of the object. 556881SN/A */ 566881SN/Aclass ClockedObject : public SimObject 576285SN/A{ 588257SBrad.Beckmann@amd.com 598257SBrad.Beckmann@amd.com private: 608257SBrad.Beckmann@amd.com 618257SBrad.Beckmann@amd.com // the tick value of the next clock edge (>= curTick()) at the 629594Snilay@cs.wisc.edu // time of the last call to update() 639594Snilay@cs.wisc.edu mutable Tick tick; 648257SBrad.Beckmann@amd.com 658257SBrad.Beckmann@amd.com // The cycle counter value corresponding to the current value of 668257SBrad.Beckmann@amd.com // 'tick' 676881SN/A mutable Cycles cycle; 6810078Snilay@cs.wisc.edu 699869Sjthestness@gmail.com /** 707054SN/A * Prevent inadvertent use of the copy constructor and assignment 718257SBrad.Beckmann@amd.com * operator by making them private. 726145SN/A */ 738257SBrad.Beckmann@amd.com ClockedObject(ClockedObject&); 748257SBrad.Beckmann@amd.com ClockedObject& operator=(ClockedObject&); 758257SBrad.Beckmann@amd.com 768257SBrad.Beckmann@amd.com /** 778257SBrad.Beckmann@amd.com * Align cycle and tick to the next clock edge if not already done. 787054SN/A */ 796145SN/A void update() const 809594Snilay@cs.wisc.edu { 819594Snilay@cs.wisc.edu // both tick and cycle are up-to-date and we are done, note 828257SBrad.Beckmann@amd.com // that the >= is important as it captures cases where tick 838257SBrad.Beckmann@amd.com // has already passed curTick() 848257SBrad.Beckmann@amd.com if (tick >= curTick()) 856881SN/A return; 868257SBrad.Beckmann@amd.com 878257SBrad.Beckmann@amd.com // optimise for the common case and see if the tick should be 888257SBrad.Beckmann@amd.com // advanced by a single clock period 898257SBrad.Beckmann@amd.com tick += clock; 908257SBrad.Beckmann@amd.com ++cycle; 918257SBrad.Beckmann@amd.com 928257SBrad.Beckmann@amd.com // see if we are done at this point 938257SBrad.Beckmann@amd.com if (tick >= curTick()) 948257SBrad.Beckmann@amd.com return; 958257SBrad.Beckmann@amd.com 968257SBrad.Beckmann@amd.com // if not, we have to recalculate the cycle and tick, we 977054SN/A // perform the calculations in terms of relative cycles to 986145SN/A // allow changes to the clock period in the future 996145SN/A Cycles elapsedCycles(divCeil(curTick() - tick, clock)); 1008257SBrad.Beckmann@amd.com cycle += elapsedCycles; 1019799Snilay@cs.wisc.edu tick += elapsedCycles * clock; 1027054SN/A } 1037054SN/A 1047054SN/A protected: 1058257SBrad.Beckmann@amd.com 1068257SBrad.Beckmann@amd.com // Clock period in ticks 10710005Snilay@cs.wisc.edu Tick clock; 1088257SBrad.Beckmann@amd.com 1098257SBrad.Beckmann@amd.com /** 1107054SN/A * Create a clocked object and set the clock based on the 1116881SN/A * parameters. 1128257SBrad.Beckmann@amd.com */ 1137054SN/A ClockedObject(const ClockedObjectParams* p) : 11411096Snilay@cs.wisc.edu SimObject(p), tick(0), cycle(0), clock(p->clock) 11511096Snilay@cs.wisc.edu { } 11611096Snilay@cs.wisc.edu 11711096Snilay@cs.wisc.edu /** 11811096Snilay@cs.wisc.edu * Virtual destructor due to inheritance. 11911096Snilay@cs.wisc.edu */ 1206145SN/A virtual ~ClockedObject() { } 1217054SN/A 1227054SN/A /** 1237054SN/A * Reset the object's clock using the current global tick value. Likely 1247054SN/A * to be used only when the global clock is reset. Currently, this done 1256145SN/A * only when Ruby is done warming up the memory system. 1267054SN/A */ 1278257SBrad.Beckmann@amd.com void resetClock() const 1288257SBrad.Beckmann@amd.com { 1298257SBrad.Beckmann@amd.com Cycles elapsedCycles(divCeil(curTick(), clock)); 1308257SBrad.Beckmann@amd.com cycle = elapsedCycles; 1318257SBrad.Beckmann@amd.com tick = elapsedCycles * clock; 1328257SBrad.Beckmann@amd.com } 13311096Snilay@cs.wisc.edu 1348257SBrad.Beckmann@amd.com public: 1357054SN/A 1368257SBrad.Beckmann@amd.com /** 1377054SN/A * Determine the tick when a cycle begins, by default the current 13811096Snilay@cs.wisc.edu * one, but the argument also enables the caller to determine a 13911096Snilay@cs.wisc.edu * future cycle. 14011096Snilay@cs.wisc.edu * 1417054SN/A * @param cycles The number of cycles into the future 1427054SN/A * 1437054SN/A * @return The tick when the clock edge occurs 1447054SN/A */ 1459799Snilay@cs.wisc.edu inline Tick clockEdge(Cycles cycles = Cycles(0)) const 1469799Snilay@cs.wisc.edu { 1479799Snilay@cs.wisc.edu // align tick to the next clock edge 1487054SN/A update(); 1497054SN/A 1506895SN/A // figure out when this future cycle is 1516895SN/A return tick + clock * cycles; 1526895SN/A } 1537054SN/A 1548257SBrad.Beckmann@amd.com /** 1558257SBrad.Beckmann@amd.com * Determine the current cycle, corresponding to a tick aligned to 1567054SN/A * a clock edge. 1577832SN/A * 1587832SN/A * @return The current cycle count 1598257SBrad.Beckmann@amd.com */ 1608257SBrad.Beckmann@amd.com inline Cycles curCycle() const 1618257SBrad.Beckmann@amd.com { 1628257SBrad.Beckmann@amd.com // align cycle to the next clock edge. 1638257SBrad.Beckmann@amd.com update(); 1648257SBrad.Beckmann@amd.com 1658257SBrad.Beckmann@amd.com return cycle; 1668257SBrad.Beckmann@amd.com } 1678257SBrad.Beckmann@amd.com 1687054SN/A /** 1697054SN/A * Based on the clock of the object, determine the tick when the 1707054SN/A * next cycle begins, in other words, return the next clock edge. 1717054SN/A * 1729799Snilay@cs.wisc.edu * @return The tick when the next cycle starts 1737054SN/A */ 1747054SN/A Tick nextCycle() const 1757054SN/A { return clockEdge(); } 1767054SN/A 1777054SN/A inline uint64_t frequency() const { return SimClock::Frequency / clock; } 1788257SBrad.Beckmann@amd.com 1798257SBrad.Beckmann@amd.com inline Tick clockPeriod() const { return clock; } 1808257SBrad.Beckmann@amd.com 1817054SN/A inline Cycles ticksToCycles(Tick tick) const 1828257SBrad.Beckmann@amd.com { return Cycles(tick / clock); } 1838257SBrad.Beckmann@amd.com 1848257SBrad.Beckmann@amd.com}; 1858257SBrad.Beckmann@amd.com 1869799Snilay@cs.wisc.edu#endif //__SIM_CLOCKED_OBJECT_HH__ 1877054SN/A