clocked_object.hh revision 9356
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"
509356Snilay@cs.wisc.edu#include "sim/core.hh"
519157Sandreas.hansson@arm.com#include "sim/sim_object.hh"
529157Sandreas.hansson@arm.com
539157Sandreas.hansson@arm.com/**
549157Sandreas.hansson@arm.com * The ClockedObject class extends the SimObject with a clock and
559157Sandreas.hansson@arm.com * accessor functions to relate ticks to the cycles of the object.
569157Sandreas.hansson@arm.com */
579157Sandreas.hansson@arm.comclass ClockedObject : public SimObject
589157Sandreas.hansson@arm.com{
599157Sandreas.hansson@arm.com
609157Sandreas.hansson@arm.com  private:
619157Sandreas.hansson@arm.com
629179Sandreas.hansson@arm.com    // the tick value of the next clock edge (>= curTick()) at the
639179Sandreas.hansson@arm.com    // time of the last call to update()
649179Sandreas.hansson@arm.com    mutable Tick tick;
659179Sandreas.hansson@arm.com
669179Sandreas.hansson@arm.com    // The cycle counter value corresponding to the current value of
679179Sandreas.hansson@arm.com    // 'tick'
689180Sandreas.hansson@arm.com    mutable Cycles cycle;
699179Sandreas.hansson@arm.com
709157Sandreas.hansson@arm.com    /**
719157Sandreas.hansson@arm.com     * Prevent inadvertent use of the copy constructor and assignment
729157Sandreas.hansson@arm.com     * operator by making them private.
739157Sandreas.hansson@arm.com     */
749157Sandreas.hansson@arm.com    ClockedObject(ClockedObject&);
759157Sandreas.hansson@arm.com    ClockedObject& operator=(ClockedObject&);
769157Sandreas.hansson@arm.com
779179Sandreas.hansson@arm.com    /**
789179Sandreas.hansson@arm.com     *  Align cycle and tick to the next clock edge if not already done.
799179Sandreas.hansson@arm.com     */
809179Sandreas.hansson@arm.com    void update() const
819179Sandreas.hansson@arm.com    {
829179Sandreas.hansson@arm.com        // both tick and cycle are up-to-date and we are done, note
839179Sandreas.hansson@arm.com        // that the >= is important as it captures cases where tick
849179Sandreas.hansson@arm.com        // has already passed curTick()
859179Sandreas.hansson@arm.com        if (tick >= curTick())
869179Sandreas.hansson@arm.com            return;
879179Sandreas.hansson@arm.com
889179Sandreas.hansson@arm.com        // optimise for the common case and see if the tick should be
899179Sandreas.hansson@arm.com        // advanced by a single clock period
909179Sandreas.hansson@arm.com        tick += clock;
919179Sandreas.hansson@arm.com        ++cycle;
929179Sandreas.hansson@arm.com
939179Sandreas.hansson@arm.com        // see if we are done at this point
949179Sandreas.hansson@arm.com        if (tick >= curTick())
959179Sandreas.hansson@arm.com            return;
969179Sandreas.hansson@arm.com
979179Sandreas.hansson@arm.com        // if not, we have to recalculate the cycle and tick, we
989179Sandreas.hansson@arm.com        // perform the calculations in terms of relative cycles to
999179Sandreas.hansson@arm.com        // allow changes to the clock period in the future
1009180Sandreas.hansson@arm.com        Cycles elapsedCycles(divCeil(curTick() - tick, clock));
1019179Sandreas.hansson@arm.com        cycle += elapsedCycles;
1029179Sandreas.hansson@arm.com        tick += elapsedCycles * clock;
1039179Sandreas.hansson@arm.com    }
1049179Sandreas.hansson@arm.com
1059157Sandreas.hansson@arm.com  protected:
1069157Sandreas.hansson@arm.com
1079157Sandreas.hansson@arm.com    // Clock period in ticks
1089157Sandreas.hansson@arm.com    Tick clock;
1099157Sandreas.hansson@arm.com
1109157Sandreas.hansson@arm.com    /**
1119157Sandreas.hansson@arm.com     * Create a clocked object and set the clock based on the
1129157Sandreas.hansson@arm.com     * parameters.
1139157Sandreas.hansson@arm.com     */
1149179Sandreas.hansson@arm.com    ClockedObject(const ClockedObjectParams* p) :
1159179Sandreas.hansson@arm.com        SimObject(p), tick(0), cycle(0), clock(p->clock)
1169157Sandreas.hansson@arm.com    { }
1179157Sandreas.hansson@arm.com
1189157Sandreas.hansson@arm.com    /**
1199157Sandreas.hansson@arm.com     * Virtual destructor due to inheritance.
1209157Sandreas.hansson@arm.com     */
1219157Sandreas.hansson@arm.com    virtual ~ClockedObject() { }
1229157Sandreas.hansson@arm.com
1239296Snilay@cs.wisc.edu    /**
1249296Snilay@cs.wisc.edu     * Reset the object's clock using the current global tick value. Likely
1259296Snilay@cs.wisc.edu     * to be used only when the global clock is reset. Currently, this done
1269296Snilay@cs.wisc.edu     * only when Ruby is done warming up the memory system.
1279296Snilay@cs.wisc.edu     */
1289296Snilay@cs.wisc.edu    void resetClock() const
1299296Snilay@cs.wisc.edu    {
1309296Snilay@cs.wisc.edu        Cycles elapsedCycles(divCeil(curTick(), clock));
1319296Snilay@cs.wisc.edu        cycle = elapsedCycles;
1329296Snilay@cs.wisc.edu        tick = elapsedCycles * clock;
1339296Snilay@cs.wisc.edu    }
1349296Snilay@cs.wisc.edu
1359157Sandreas.hansson@arm.com  public:
1369157Sandreas.hansson@arm.com
1379157Sandreas.hansson@arm.com    /**
1389179Sandreas.hansson@arm.com     * Determine the tick when a cycle begins, by default the current
1399179Sandreas.hansson@arm.com     * one, but the argument also enables the caller to determine a
1409179Sandreas.hansson@arm.com     * future cycle.
1419179Sandreas.hansson@arm.com     *
1429179Sandreas.hansson@arm.com     * @param cycles The number of cycles into the future
1439179Sandreas.hansson@arm.com     *
1449179Sandreas.hansson@arm.com     * @return The tick when the clock edge occurs
1459179Sandreas.hansson@arm.com     */
1469180Sandreas.hansson@arm.com    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
1479179Sandreas.hansson@arm.com    {
1489179Sandreas.hansson@arm.com        // align tick to the next clock edge
1499179Sandreas.hansson@arm.com        update();
1509179Sandreas.hansson@arm.com
1519179Sandreas.hansson@arm.com        // figure out when this future cycle is
1529180Sandreas.hansson@arm.com        return tick + clock * cycles;
1539179Sandreas.hansson@arm.com    }
1549179Sandreas.hansson@arm.com
1559179Sandreas.hansson@arm.com    /**
1569179Sandreas.hansson@arm.com     * Determine the current cycle, corresponding to a tick aligned to
1579179Sandreas.hansson@arm.com     * a clock edge.
1589179Sandreas.hansson@arm.com     *
1599180Sandreas.hansson@arm.com     * @return The current cycle count
1609179Sandreas.hansson@arm.com     */
1619180Sandreas.hansson@arm.com    inline Cycles curCycle() const
1629179Sandreas.hansson@arm.com    {
1639179Sandreas.hansson@arm.com        // align cycle to the next clock edge.
1649179Sandreas.hansson@arm.com        update();
1659179Sandreas.hansson@arm.com
1669179Sandreas.hansson@arm.com        return cycle;
1679179Sandreas.hansson@arm.com    }
1689179Sandreas.hansson@arm.com
1699179Sandreas.hansson@arm.com    /**
1709157Sandreas.hansson@arm.com     * Based on the clock of the object, determine the tick when the
1719179Sandreas.hansson@arm.com     * next cycle begins, in other words, return the next clock edge.
1729157Sandreas.hansson@arm.com     *
1739157Sandreas.hansson@arm.com     * @return The tick when the next cycle starts
1749157Sandreas.hansson@arm.com     */
1759157Sandreas.hansson@arm.com    Tick nextCycle() const
1769179Sandreas.hansson@arm.com    { return clockEdge(); }
1779157Sandreas.hansson@arm.com
1789180Sandreas.hansson@arm.com    inline uint64_t frequency() const { return SimClock::Frequency / clock; }
1799157Sandreas.hansson@arm.com
1809179Sandreas.hansson@arm.com    inline Tick clockPeriod() const { return clock; }
1819157Sandreas.hansson@arm.com
1829180Sandreas.hansson@arm.com    inline Cycles ticksToCycles(Tick tick) const
1839180Sandreas.hansson@arm.com    { return Cycles(tick / clock); }
1849157Sandreas.hansson@arm.com
1859157Sandreas.hansson@arm.com};
1869157Sandreas.hansson@arm.com
1879157Sandreas.hansson@arm.com#endif //__SIM_CLOCKED_OBJECT_HH__
188