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