clocked_object.hh revision 10000
19157Sandreas.hansson@arm.com/*
29793Sakash.bagdia@arm.com * Copyright (c) 2012-2013 ARM Limited
310000Sclt67@cornell.edu * Copyright (c) 2013 Cornell University
49157Sandreas.hansson@arm.com * All rights reserved
59157Sandreas.hansson@arm.com *
69157Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
79157Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
89157Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
99157Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
109157Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
119157Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
129157Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
139157Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
149157Sandreas.hansson@arm.com *
159157Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
169157Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
179157Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
189157Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
199157Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
209157Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
219157Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
229157Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
239157Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
249157Sandreas.hansson@arm.com * this software without specific prior written permission.
259157Sandreas.hansson@arm.com *
269157Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
279157Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
289157Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
299157Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
309157Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
319157Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
329157Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
339157Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
349157Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
359157Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
369157Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
379157Sandreas.hansson@arm.com *
389157Sandreas.hansson@arm.com * Authors: Andreas Hansson
3910000Sclt67@cornell.edu *          Christopher Torng
409157Sandreas.hansson@arm.com */
419157Sandreas.hansson@arm.com
429157Sandreas.hansson@arm.com/**
439157Sandreas.hansson@arm.com * @file
449157Sandreas.hansson@arm.com * ClockedObject declaration and implementation.
459157Sandreas.hansson@arm.com */
469157Sandreas.hansson@arm.com
479157Sandreas.hansson@arm.com#ifndef __SIM_CLOCKED_OBJECT_HH__
489157Sandreas.hansson@arm.com#define __SIM_CLOCKED_OBJECT_HH__
499157Sandreas.hansson@arm.com
509157Sandreas.hansson@arm.com#include "base/intmath.hh"
519418Sandreas.hansson@arm.com#include "base/misc.hh"
529157Sandreas.hansson@arm.com#include "params/ClockedObject.hh"
539356Snilay@cs.wisc.edu#include "sim/core.hh"
549793Sakash.bagdia@arm.com#include "sim/clock_domain.hh"
559157Sandreas.hansson@arm.com#include "sim/sim_object.hh"
569157Sandreas.hansson@arm.com
579157Sandreas.hansson@arm.com/**
589157Sandreas.hansson@arm.com * The ClockedObject class extends the SimObject with a clock and
599157Sandreas.hansson@arm.com * accessor functions to relate ticks to the cycles of the object.
609157Sandreas.hansson@arm.com */
619157Sandreas.hansson@arm.comclass ClockedObject : public SimObject
629157Sandreas.hansson@arm.com{
639157Sandreas.hansson@arm.com
649157Sandreas.hansson@arm.com  private:
659157Sandreas.hansson@arm.com
669179Sandreas.hansson@arm.com    // the tick value of the next clock edge (>= curTick()) at the
679179Sandreas.hansson@arm.com    // time of the last call to update()
689179Sandreas.hansson@arm.com    mutable Tick tick;
699179Sandreas.hansson@arm.com
709179Sandreas.hansson@arm.com    // The cycle counter value corresponding to the current value of
719179Sandreas.hansson@arm.com    // 'tick'
729180Sandreas.hansson@arm.com    mutable Cycles cycle;
739179Sandreas.hansson@arm.com
749157Sandreas.hansson@arm.com    /**
759157Sandreas.hansson@arm.com     * Prevent inadvertent use of the copy constructor and assignment
769157Sandreas.hansson@arm.com     * operator by making them private.
779157Sandreas.hansson@arm.com     */
789157Sandreas.hansson@arm.com    ClockedObject(ClockedObject&);
799157Sandreas.hansson@arm.com    ClockedObject& operator=(ClockedObject&);
809157Sandreas.hansson@arm.com
819179Sandreas.hansson@arm.com    /**
829179Sandreas.hansson@arm.com     *  Align cycle and tick to the next clock edge if not already done.
839179Sandreas.hansson@arm.com     */
849179Sandreas.hansson@arm.com    void update() const
859179Sandreas.hansson@arm.com    {
869179Sandreas.hansson@arm.com        // both tick and cycle are up-to-date and we are done, note
879179Sandreas.hansson@arm.com        // that the >= is important as it captures cases where tick
889179Sandreas.hansson@arm.com        // has already passed curTick()
899179Sandreas.hansson@arm.com        if (tick >= curTick())
909179Sandreas.hansson@arm.com            return;
919179Sandreas.hansson@arm.com
929179Sandreas.hansson@arm.com        // optimise for the common case and see if the tick should be
939179Sandreas.hansson@arm.com        // advanced by a single clock period
949793Sakash.bagdia@arm.com        tick += clockPeriod();
959179Sandreas.hansson@arm.com        ++cycle;
969179Sandreas.hansson@arm.com
979179Sandreas.hansson@arm.com        // see if we are done at this point
989179Sandreas.hansson@arm.com        if (tick >= curTick())
999179Sandreas.hansson@arm.com            return;
1009179Sandreas.hansson@arm.com
1019179Sandreas.hansson@arm.com        // if not, we have to recalculate the cycle and tick, we
1029179Sandreas.hansson@arm.com        // perform the calculations in terms of relative cycles to
1039179Sandreas.hansson@arm.com        // allow changes to the clock period in the future
1049793Sakash.bagdia@arm.com        Cycles elapsedCycles(divCeil(curTick() - tick, clockPeriod()));
1059179Sandreas.hansson@arm.com        cycle += elapsedCycles;
1069793Sakash.bagdia@arm.com        tick += elapsedCycles * clockPeriod();
1079179Sandreas.hansson@arm.com    }
1089179Sandreas.hansson@arm.com
1099793Sakash.bagdia@arm.com    /**
1109793Sakash.bagdia@arm.com     * The clock domain this clocked object belongs to
1119793Sakash.bagdia@arm.com     */
1129793Sakash.bagdia@arm.com    ClockDomain &clockDomain;
1139157Sandreas.hansson@arm.com
1149545Sandreas.hansson@arm.com  protected:
1159545Sandreas.hansson@arm.com
1169157Sandreas.hansson@arm.com    /**
1179793Sakash.bagdia@arm.com     * Create a clocked object and set the clock domain based on the
1189157Sandreas.hansson@arm.com     * parameters.
1199157Sandreas.hansson@arm.com     */
1209179Sandreas.hansson@arm.com    ClockedObject(const ClockedObjectParams* p) :
1219793Sakash.bagdia@arm.com        SimObject(p), tick(0), cycle(0), clockDomain(*p->clk_domain)
1229418Sandreas.hansson@arm.com    {
12310000Sclt67@cornell.edu        // Register with the clock domain, so that if the clock domain
12410000Sclt67@cornell.edu        // frequency changes, we can update this object's tick.
12510000Sclt67@cornell.edu        clockDomain.registerWithClockDomain(this);
1269418Sandreas.hansson@arm.com    }
1279157Sandreas.hansson@arm.com
1289157Sandreas.hansson@arm.com    /**
1299157Sandreas.hansson@arm.com     * Virtual destructor due to inheritance.
1309157Sandreas.hansson@arm.com     */
1319157Sandreas.hansson@arm.com    virtual ~ClockedObject() { }
1329157Sandreas.hansson@arm.com
1339296Snilay@cs.wisc.edu    /**
1349296Snilay@cs.wisc.edu     * Reset the object's clock using the current global tick value. Likely
1359296Snilay@cs.wisc.edu     * to be used only when the global clock is reset. Currently, this done
1369296Snilay@cs.wisc.edu     * only when Ruby is done warming up the memory system.
1379296Snilay@cs.wisc.edu     */
1389296Snilay@cs.wisc.edu    void resetClock() const
1399296Snilay@cs.wisc.edu    {
1409793Sakash.bagdia@arm.com        Cycles elapsedCycles(divCeil(curTick(), clockPeriod()));
1419296Snilay@cs.wisc.edu        cycle = elapsedCycles;
1429793Sakash.bagdia@arm.com        tick = elapsedCycles * clockPeriod();
1439296Snilay@cs.wisc.edu    }
1449296Snilay@cs.wisc.edu
1459157Sandreas.hansson@arm.com  public:
1469157Sandreas.hansson@arm.com
1479157Sandreas.hansson@arm.com    /**
14810000Sclt67@cornell.edu     * Update the tick to the current tick.
14910000Sclt67@cornell.edu     *
15010000Sclt67@cornell.edu     */
15110000Sclt67@cornell.edu    inline void updateClockPeriod() const
15210000Sclt67@cornell.edu    {
15310000Sclt67@cornell.edu        update();
15410000Sclt67@cornell.edu    }
15510000Sclt67@cornell.edu
15610000Sclt67@cornell.edu    /**
1579179Sandreas.hansson@arm.com     * Determine the tick when a cycle begins, by default the current
1589179Sandreas.hansson@arm.com     * one, but the argument also enables the caller to determine a
1599179Sandreas.hansson@arm.com     * future cycle.
1609179Sandreas.hansson@arm.com     *
1619179Sandreas.hansson@arm.com     * @param cycles The number of cycles into the future
1629179Sandreas.hansson@arm.com     *
1639179Sandreas.hansson@arm.com     * @return The tick when the clock edge occurs
1649179Sandreas.hansson@arm.com     */
1659180Sandreas.hansson@arm.com    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
1669179Sandreas.hansson@arm.com    {
1679179Sandreas.hansson@arm.com        // align tick to the next clock edge
1689179Sandreas.hansson@arm.com        update();
1699179Sandreas.hansson@arm.com
1709179Sandreas.hansson@arm.com        // figure out when this future cycle is
1719793Sakash.bagdia@arm.com        return tick + clockPeriod() * cycles;
1729179Sandreas.hansson@arm.com    }
1739179Sandreas.hansson@arm.com
1749179Sandreas.hansson@arm.com    /**
1759179Sandreas.hansson@arm.com     * Determine the current cycle, corresponding to a tick aligned to
1769179Sandreas.hansson@arm.com     * a clock edge.
1779179Sandreas.hansson@arm.com     *
1789180Sandreas.hansson@arm.com     * @return The current cycle count
1799179Sandreas.hansson@arm.com     */
1809180Sandreas.hansson@arm.com    inline Cycles curCycle() const
1819179Sandreas.hansson@arm.com    {
1829179Sandreas.hansson@arm.com        // align cycle to the next clock edge.
1839179Sandreas.hansson@arm.com        update();
1849179Sandreas.hansson@arm.com
1859179Sandreas.hansson@arm.com        return cycle;
1869179Sandreas.hansson@arm.com    }
1879179Sandreas.hansson@arm.com
1889179Sandreas.hansson@arm.com    /**
1899648Sdam.sunwoo@arm.com     * Based on the clock of the object, determine the tick when the next
1909648Sdam.sunwoo@arm.com     * cycle begins, in other words, return the next clock edge.
1919648Sdam.sunwoo@arm.com     * (This can never be the current tick.)
1929157Sandreas.hansson@arm.com     *
1939157Sandreas.hansson@arm.com     * @return The tick when the next cycle starts
1949157Sandreas.hansson@arm.com     */
1959157Sandreas.hansson@arm.com    Tick nextCycle() const
1969648Sdam.sunwoo@arm.com    { return clockEdge(Cycles(1)); }
1979157Sandreas.hansson@arm.com
1989793Sakash.bagdia@arm.com    inline uint64_t frequency() const
1999793Sakash.bagdia@arm.com    {
2009793Sakash.bagdia@arm.com        return SimClock::Frequency / clockPeriod();
2019793Sakash.bagdia@arm.com    }
2029157Sandreas.hansson@arm.com
2039793Sakash.bagdia@arm.com    inline Tick clockPeriod() const
2049793Sakash.bagdia@arm.com    {
2059793Sakash.bagdia@arm.com        return clockDomain.clockPeriod();
2069793Sakash.bagdia@arm.com    }
2079157Sandreas.hansson@arm.com
2089550Sandreas.hansson@arm.com    inline Cycles ticksToCycles(Tick t) const
2099987Snilay@cs.wisc.edu    { return Cycles(divCeil(t, clockPeriod())); }
2109157Sandreas.hansson@arm.com
2119157Sandreas.hansson@arm.com};
2129157Sandreas.hansson@arm.com
2139157Sandreas.hansson@arm.com#endif //__SIM_CLOCKED_OBJECT_HH__
214