clocked_object.hh revision 9296
19157Sandreas.hansson@arm.com/*
29157Sandreas.hansson@arm.com * Copyright (c) 2012 ARM Limited
39157Sandreas.hansson@arm.com * All rights reserved
49157Sandreas.hansson@arm.com *
59157Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
69157Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
79157Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
89157Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
99157Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
109157Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
119157Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
129157Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
139157Sandreas.hansson@arm.com *
149157Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
159157Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
169157Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
179157Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
189157Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
199157Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
209157Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
219157Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
229157Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
239157Sandreas.hansson@arm.com * this software without specific prior written permission.
249157Sandreas.hansson@arm.com *
259157Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
269157Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
279157Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
289157Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
299157Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
309157Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
319157Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
329157Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
339157Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
349157Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
359157Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
369157Sandreas.hansson@arm.com *
379157Sandreas.hansson@arm.com * Authors: Andreas Hansson
389157Sandreas.hansson@arm.com */
399157Sandreas.hansson@arm.com
409157Sandreas.hansson@arm.com/**
419157Sandreas.hansson@arm.com * @file
429157Sandreas.hansson@arm.com * ClockedObject declaration and implementation.
439157Sandreas.hansson@arm.com */
449157Sandreas.hansson@arm.com
459157Sandreas.hansson@arm.com#ifndef __SIM_CLOCKED_OBJECT_HH__
469157Sandreas.hansson@arm.com#define __SIM_CLOCKED_OBJECT_HH__
479157Sandreas.hansson@arm.com
489157Sandreas.hansson@arm.com#include "base/intmath.hh"
499157Sandreas.hansson@arm.com#include "params/ClockedObject.hh"
509157Sandreas.hansson@arm.com#include "sim/sim_object.hh"
519157Sandreas.hansson@arm.com
529157Sandreas.hansson@arm.com/**
539157Sandreas.hansson@arm.com * The ClockedObject class extends the SimObject with a clock and
549157Sandreas.hansson@arm.com * accessor functions to relate ticks to the cycles of the object.
559157Sandreas.hansson@arm.com */
569157Sandreas.hansson@arm.comclass ClockedObject : public SimObject
579157Sandreas.hansson@arm.com{
589157Sandreas.hansson@arm.com
599157Sandreas.hansson@arm.com  private:
609157Sandreas.hansson@arm.com
619179Sandreas.hansson@arm.com    // the tick value of the next clock edge (>= curTick()) at the
629179Sandreas.hansson@arm.com    // time of the last call to update()
639179Sandreas.hansson@arm.com    mutable Tick tick;
649179Sandreas.hansson@arm.com
659179Sandreas.hansson@arm.com    // The cycle counter value corresponding to the current value of
669179Sandreas.hansson@arm.com    // 'tick'
679180Sandreas.hansson@arm.com    mutable Cycles cycle;
689179Sandreas.hansson@arm.com
699157Sandreas.hansson@arm.com    /**
709157Sandreas.hansson@arm.com     * Prevent inadvertent use of the copy constructor and assignment
719157Sandreas.hansson@arm.com     * operator by making them private.
729157Sandreas.hansson@arm.com     */
739157Sandreas.hansson@arm.com    ClockedObject(ClockedObject&);
749157Sandreas.hansson@arm.com    ClockedObject& operator=(ClockedObject&);
759157Sandreas.hansson@arm.com
769179Sandreas.hansson@arm.com    /**
779179Sandreas.hansson@arm.com     *  Align cycle and tick to the next clock edge if not already done.
789179Sandreas.hansson@arm.com     */
799179Sandreas.hansson@arm.com    void update() const
809179Sandreas.hansson@arm.com    {
819179Sandreas.hansson@arm.com        // both tick and cycle are up-to-date and we are done, note
829179Sandreas.hansson@arm.com        // that the >= is important as it captures cases where tick
839179Sandreas.hansson@arm.com        // has already passed curTick()
849179Sandreas.hansson@arm.com        if (tick >= curTick())
859179Sandreas.hansson@arm.com            return;
869179Sandreas.hansson@arm.com
879179Sandreas.hansson@arm.com        // optimise for the common case and see if the tick should be
889179Sandreas.hansson@arm.com        // advanced by a single clock period
899179Sandreas.hansson@arm.com        tick += clock;
909179Sandreas.hansson@arm.com        ++cycle;
919179Sandreas.hansson@arm.com
929179Sandreas.hansson@arm.com        // see if we are done at this point
939179Sandreas.hansson@arm.com        if (tick >= curTick())
949179Sandreas.hansson@arm.com            return;
959179Sandreas.hansson@arm.com
969179Sandreas.hansson@arm.com        // if not, we have to recalculate the cycle and tick, we
979179Sandreas.hansson@arm.com        // perform the calculations in terms of relative cycles to
989179Sandreas.hansson@arm.com        // allow changes to the clock period in the future
999180Sandreas.hansson@arm.com        Cycles elapsedCycles(divCeil(curTick() - tick, clock));
1009179Sandreas.hansson@arm.com        cycle += elapsedCycles;
1019179Sandreas.hansson@arm.com        tick += elapsedCycles * clock;
1029179Sandreas.hansson@arm.com    }
1039179Sandreas.hansson@arm.com
1049157Sandreas.hansson@arm.com  protected:
1059157Sandreas.hansson@arm.com
1069157Sandreas.hansson@arm.com    // Clock period in ticks
1079157Sandreas.hansson@arm.com    Tick clock;
1089157Sandreas.hansson@arm.com
1099157Sandreas.hansson@arm.com    /**
1109157Sandreas.hansson@arm.com     * Create a clocked object and set the clock based on the
1119157Sandreas.hansson@arm.com     * parameters.
1129157Sandreas.hansson@arm.com     */
1139179Sandreas.hansson@arm.com    ClockedObject(const ClockedObjectParams* p) :
1149179Sandreas.hansson@arm.com        SimObject(p), tick(0), cycle(0), clock(p->clock)
1159157Sandreas.hansson@arm.com    { }
1169157Sandreas.hansson@arm.com
1179157Sandreas.hansson@arm.com    /**
1189157Sandreas.hansson@arm.com     * Virtual destructor due to inheritance.
1199157Sandreas.hansson@arm.com     */
1209157Sandreas.hansson@arm.com    virtual ~ClockedObject() { }
1219157Sandreas.hansson@arm.com
1229296Snilay@cs.wisc.edu    /**
1239296Snilay@cs.wisc.edu     * Reset the object's clock using the current global tick value. Likely
1249296Snilay@cs.wisc.edu     * to be used only when the global clock is reset. Currently, this done
1259296Snilay@cs.wisc.edu     * only when Ruby is done warming up the memory system.
1269296Snilay@cs.wisc.edu     */
1279296Snilay@cs.wisc.edu    void resetClock() const
1289296Snilay@cs.wisc.edu    {
1299296Snilay@cs.wisc.edu        Cycles elapsedCycles(divCeil(curTick(), clock));
1309296Snilay@cs.wisc.edu        cycle = elapsedCycles;
1319296Snilay@cs.wisc.edu        tick = elapsedCycles * clock;
1329296Snilay@cs.wisc.edu    }
1339296Snilay@cs.wisc.edu
1349157Sandreas.hansson@arm.com  public:
1359157Sandreas.hansson@arm.com
1369157Sandreas.hansson@arm.com    /**
1379179Sandreas.hansson@arm.com     * Determine the tick when a cycle begins, by default the current
1389179Sandreas.hansson@arm.com     * one, but the argument also enables the caller to determine a
1399179Sandreas.hansson@arm.com     * future cycle.
1409179Sandreas.hansson@arm.com     *
1419179Sandreas.hansson@arm.com     * @param cycles The number of cycles into the future
1429179Sandreas.hansson@arm.com     *
1439179Sandreas.hansson@arm.com     * @return The tick when the clock edge occurs
1449179Sandreas.hansson@arm.com     */
1459180Sandreas.hansson@arm.com    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
1469179Sandreas.hansson@arm.com    {
1479179Sandreas.hansson@arm.com        // align tick to the next clock edge
1489179Sandreas.hansson@arm.com        update();
1499179Sandreas.hansson@arm.com
1509179Sandreas.hansson@arm.com        // figure out when this future cycle is
1519180Sandreas.hansson@arm.com        return tick + clock * cycles;
1529179Sandreas.hansson@arm.com    }
1539179Sandreas.hansson@arm.com
1549179Sandreas.hansson@arm.com    /**
1559179Sandreas.hansson@arm.com     * Determine the current cycle, corresponding to a tick aligned to
1569179Sandreas.hansson@arm.com     * a clock edge.
1579179Sandreas.hansson@arm.com     *
1589180Sandreas.hansson@arm.com     * @return The current cycle count
1599179Sandreas.hansson@arm.com     */
1609180Sandreas.hansson@arm.com    inline Cycles curCycle() const
1619179Sandreas.hansson@arm.com    {
1629179Sandreas.hansson@arm.com        // align cycle to the next clock edge.
1639179Sandreas.hansson@arm.com        update();
1649179Sandreas.hansson@arm.com
1659179Sandreas.hansson@arm.com        return cycle;
1669179Sandreas.hansson@arm.com    }
1679179Sandreas.hansson@arm.com
1689179Sandreas.hansson@arm.com    /**
1699157Sandreas.hansson@arm.com     * Based on the clock of the object, determine the tick when the
1709179Sandreas.hansson@arm.com     * next cycle begins, in other words, return the next clock edge.
1719157Sandreas.hansson@arm.com     *
1729157Sandreas.hansson@arm.com     * @return The tick when the next cycle starts
1739157Sandreas.hansson@arm.com     */
1749157Sandreas.hansson@arm.com    Tick nextCycle() const
1759179Sandreas.hansson@arm.com    { return clockEdge(); }
1769157Sandreas.hansson@arm.com
1779180Sandreas.hansson@arm.com    inline uint64_t frequency() const { return SimClock::Frequency / clock; }
1789157Sandreas.hansson@arm.com
1799179Sandreas.hansson@arm.com    inline Tick clockPeriod() const { return clock; }
1809157Sandreas.hansson@arm.com
1819180Sandreas.hansson@arm.com    inline Cycles ticksToCycles(Tick tick) const
1829180Sandreas.hansson@arm.com    { return Cycles(tick / clock); }
1839157Sandreas.hansson@arm.com
1849157Sandreas.hansson@arm.com};
1859157Sandreas.hansson@arm.com
1869157Sandreas.hansson@arm.com#endif //__SIM_CLOCKED_OBJECT_HH__
187