clocked_object.hh revision 9545:508784fad4e5
12330SN/A/*
29426SAndreas.Sandberg@ARM.com * Copyright (c) 2012 ARM Limited
39920Syasuko.eckert@amd.com * All rights reserved
48733Sgeoffrey.blake@arm.com *
58733Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall
68733Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual
78733Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating
88733Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software
98733Sgeoffrey.blake@arm.com * licensed hereunder.  You may use the software subject to the license
108733Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated
118733Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software,
128733Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form.
138733Sgeoffrey.blake@arm.com *
148733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without
152330SN/A * modification, are permitted provided that the following conditions are
162330SN/A * met: redistributions of source code must retain the above copyright
172330SN/A * notice, this list of conditions and the following disclaimer;
182330SN/A * redistributions in binary form must reproduce the above copyright
192330SN/A * notice, this list of conditions and the following disclaimer in the
202330SN/A * documentation and/or other materials provided with the distribution;
212330SN/A * neither the name of the copyright holders nor the names of its
222330SN/A * contributors may be used to endorse or promote products derived from
232330SN/A * this software without specific prior written permission.
242330SN/A *
252330SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262330SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272330SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282330SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292330SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302330SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312330SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322330SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332330SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342330SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352330SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362330SN/A *
372330SN/A * Authors: Andreas Hansson
382330SN/A */
392330SN/A
402689Sktlim@umich.edu/**
412689Sktlim@umich.edu * @file
422330SN/A * ClockedObject declaration and implementation.
432330SN/A */
442683Sktlim@umich.edu
452683Sktlim@umich.edu#ifndef __SIM_CLOCKED_OBJECT_HH__
462315SN/A#define __SIM_CLOCKED_OBJECT_HH__
472972Sgblack@eecs.umich.edu
486658Snate@binkert.org#include "base/intmath.hh"
492315SN/A#include "base/misc.hh"
502683Sktlim@umich.edu#include "params/ClockedObject.hh"
512680SN/A#include "sim/core.hh"
528733Sgeoffrey.blake@arm.com#include "sim/sim_object.hh"
532315SN/A
542315SN/A/**
553548Sgblack@eecs.umich.edu * The ClockedObject class extends the SimObject with a clock and
563548Sgblack@eecs.umich.edu * accessor functions to relate ticks to the cycles of the object.
573548Sgblack@eecs.umich.edu */
583548Sgblack@eecs.umich.educlass ClockedObject : public SimObject
599020Sgblack@eecs.umich.edu{
602330SN/A
612315SN/A  private:
622350SN/A
632680SN/A    // the tick value of the next clock edge (>= curTick()) at the
642680SN/A    // time of the last call to update()
652683Sktlim@umich.edu    mutable Tick tick;
662683Sktlim@umich.edu
672683Sktlim@umich.edu    // The cycle counter value corresponding to the current value of
682683Sktlim@umich.edu    // 'tick'
692350SN/A    mutable Cycles cycle;
702680SN/A
712680SN/A    /**
722315SN/A     * Prevent inadvertent use of the copy constructor and assignment
732315SN/A     * operator by making them private.
742680SN/A     */
752683Sktlim@umich.edu    ClockedObject(ClockedObject&);
762683Sktlim@umich.edu    ClockedObject& operator=(ClockedObject&);
772330SN/A
782315SN/A    /**
792315SN/A     *  Align cycle and tick to the next clock edge if not already done.
802315SN/A     */
812683Sktlim@umich.edu    void update() const
822683Sktlim@umich.edu    {
832680SN/A        // both tick and cycle are up-to-date and we are done, note
842683Sktlim@umich.edu        // that the >= is important as it captures cases where tick
852683Sktlim@umich.edu        // has already passed curTick()
862683Sktlim@umich.edu        if (tick >= curTick())
872683Sktlim@umich.edu            return;
882683Sktlim@umich.edu
892315SN/A        // optimise for the common case and see if the tick should be
902315SN/A        // advanced by a single clock period
912315SN/A        tick += clock;
922315SN/A        ++cycle;
932680SN/A
942315SN/A        // see if we are done at this point
9510190Sakash.bagdia@arm.com        if (tick >= curTick())
9610190Sakash.bagdia@arm.com            return;
9710110Sandreas.hansson@arm.com
988733Sgeoffrey.blake@arm.com        // if not, we have to recalculate the cycle and tick, we
9911005Sandreas.sandberg@arm.com        // perform the calculations in terms of relative cycles to
1008733Sgeoffrey.blake@arm.com        // allow changes to the clock period in the future
10111005Sandreas.sandberg@arm.com        Cycles elapsedCycles(divCeil(curTick() - tick, clock));
1022315SN/A        cycle += elapsedCycles;
1038733Sgeoffrey.blake@arm.com        tick += elapsedCycles * clock;
1048733Sgeoffrey.blake@arm.com    }
1052315SN/A
1062315SN/A    // Clock period in ticks
1078733Sgeoffrey.blake@arm.com    Tick clock;
10810110Sandreas.hansson@arm.com
1098733Sgeoffrey.blake@arm.com  protected:
1108733Sgeoffrey.blake@arm.com
1118733Sgeoffrey.blake@arm.com    /**
1128733Sgeoffrey.blake@arm.com     * Create a clocked object and set the clock based on the
1138733Sgeoffrey.blake@arm.com     * parameters.
1142315SN/A     */
1156022Sgblack@eecs.umich.edu    ClockedObject(const ClockedObjectParams* p) :
1164997Sgblack@eecs.umich.edu        SimObject(p), tick(0), cycle(0), clock(p->clock)
1176022Sgblack@eecs.umich.edu    {
1184997Sgblack@eecs.umich.edu        if (clock == 0) {
1198887Sgeoffrey.blake@arm.com            fatal("%s has a clock period of zero\n", name());
1208887Sgeoffrey.blake@arm.com        }
1218887Sgeoffrey.blake@arm.com    }
1228887Sgeoffrey.blake@arm.com
1238733Sgeoffrey.blake@arm.com    /**
1249020Sgblack@eecs.umich.edu     * Virtual destructor due to inheritance.
1258733Sgeoffrey.blake@arm.com     */
1262680SN/A    virtual ~ClockedObject() { }
1272315SN/A
1283548Sgblack@eecs.umich.edu    /**
1293548Sgblack@eecs.umich.edu     * Reset the object's clock using the current global tick value. Likely
1302690Sktlim@umich.edu     * to be used only when the global clock is reset. Currently, this done
1317679Sgblack@eecs.umich.edu     * only when Ruby is done warming up the memory system.
1327679Sgblack@eecs.umich.edu     */
13311886Sbrandon.potter@amd.com    void resetClock() const
13411886Sbrandon.potter@amd.com    {
1358852Sandreas.hansson@arm.com        Cycles elapsedCycles(divCeil(curTick(), clock));
1362690Sktlim@umich.edu        cycle = elapsedCycles;
1378852Sandreas.hansson@arm.com        tick = elapsedCycles * clock;
1388706Sandreas.hansson@arm.com    }
1398733Sgeoffrey.blake@arm.com
1408733Sgeoffrey.blake@arm.com  public:
1418733Sgeoffrey.blake@arm.com
1428733Sgeoffrey.blake@arm.com    /**
1438733Sgeoffrey.blake@arm.com     * Determine the tick when a cycle begins, by default the current
1448733Sgeoffrey.blake@arm.com     * one, but the argument also enables the caller to determine a
1458733Sgeoffrey.blake@arm.com     * future cycle.
1468733Sgeoffrey.blake@arm.com     *
1478809Sgblack@eecs.umich.edu     * @param cycles The number of cycles into the future
1488852Sandreas.hansson@arm.com     *
1492690Sktlim@umich.edu     * @return The tick when the clock edge occurs
1508733Sgeoffrey.blake@arm.com     */
15111877Sbrandon.potter@amd.com    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
15211877Sbrandon.potter@amd.com    {
1532315SN/A        // align tick to the next clock edge
1542680SN/A        update();
1552315SN/A
1562315SN/A        // figure out when this future cycle is
1572330SN/A        return tick + clock * cycles;
1582680SN/A    }
1592680SN/A
1602330SN/A    /**
1612315SN/A     * Determine the current cycle, corresponding to a tick aligned to
16210407Smitch.hayenga@arm.com     * a clock edge.
16310407Smitch.hayenga@arm.com     *
1642315SN/A     * @return The current cycle count
1652315SN/A     */
16610407Smitch.hayenga@arm.com    inline Cycles curCycle() const
1672315SN/A    {
1682315SN/A        // align cycle to the next clock edge.
16910407Smitch.hayenga@arm.com        update();
1702315SN/A
1712680SN/A        return cycle;
1722315SN/A    }
1732680SN/A
1742315SN/A    /**
1752680SN/A     * Based on the clock of the object, determine the tick when the
1763225Sktlim@umich.edu     * next cycle begins, in other words, return the next clock edge.
1772315SN/A     *
1782315SN/A     * @return The tick when the next cycle starts
1798733Sgeoffrey.blake@arm.com     */
1808733Sgeoffrey.blake@arm.com    Tick nextCycle() const
1818733Sgeoffrey.blake@arm.com    { return clockEdge(); }
1828733Sgeoffrey.blake@arm.com
1838733Sgeoffrey.blake@arm.com    inline uint64_t frequency() const { return SimClock::Frequency / clock; }
1842315SN/A
1852680SN/A    inline Tick clockPeriod() const { return clock; }
1862315SN/A
1872680SN/A    inline Cycles ticksToCycles(Tick tick) const
1882680SN/A    { return Cycles(tick / clock); }
1892315SN/A
1902680SN/A};
1912680SN/A
1922315SN/A#endif //__SIM_CLOCKED_OBJECT_HH__
1932315SN/A