clocked_object.hh revision 9793
19157Sandreas.hansson@arm.com/*
29793Sakash.bagdia@arm.com * Copyright (c) 2012-2013 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"
499418Sandreas.hansson@arm.com#include "base/misc.hh"
509157Sandreas.hansson@arm.com#include "params/ClockedObject.hh"
519356Snilay@cs.wisc.edu#include "sim/core.hh"
529793Sakash.bagdia@arm.com#include "sim/clock_domain.hh"
539157Sandreas.hansson@arm.com#include "sim/sim_object.hh"
549157Sandreas.hansson@arm.com
559157Sandreas.hansson@arm.com/**
569157Sandreas.hansson@arm.com * The ClockedObject class extends the SimObject with a clock and
579157Sandreas.hansson@arm.com * accessor functions to relate ticks to the cycles of the object.
589157Sandreas.hansson@arm.com */
599157Sandreas.hansson@arm.comclass ClockedObject : public SimObject
609157Sandreas.hansson@arm.com{
619157Sandreas.hansson@arm.com
629157Sandreas.hansson@arm.com  private:
639157Sandreas.hansson@arm.com
649179Sandreas.hansson@arm.com    // the tick value of the next clock edge (>= curTick()) at the
659179Sandreas.hansson@arm.com    // time of the last call to update()
669179Sandreas.hansson@arm.com    mutable Tick tick;
679179Sandreas.hansson@arm.com
689179Sandreas.hansson@arm.com    // The cycle counter value corresponding to the current value of
699179Sandreas.hansson@arm.com    // 'tick'
709180Sandreas.hansson@arm.com    mutable Cycles cycle;
719179Sandreas.hansson@arm.com
729157Sandreas.hansson@arm.com    /**
739157Sandreas.hansson@arm.com     * Prevent inadvertent use of the copy constructor and assignment
749157Sandreas.hansson@arm.com     * operator by making them private.
759157Sandreas.hansson@arm.com     */
769157Sandreas.hansson@arm.com    ClockedObject(ClockedObject&);
779157Sandreas.hansson@arm.com    ClockedObject& operator=(ClockedObject&);
789157Sandreas.hansson@arm.com
799179Sandreas.hansson@arm.com    /**
809179Sandreas.hansson@arm.com     *  Align cycle and tick to the next clock edge if not already done.
819179Sandreas.hansson@arm.com     */
829179Sandreas.hansson@arm.com    void update() const
839179Sandreas.hansson@arm.com    {
849179Sandreas.hansson@arm.com        // both tick and cycle are up-to-date and we are done, note
859179Sandreas.hansson@arm.com        // that the >= is important as it captures cases where tick
869179Sandreas.hansson@arm.com        // has already passed curTick()
879179Sandreas.hansson@arm.com        if (tick >= curTick())
889179Sandreas.hansson@arm.com            return;
899179Sandreas.hansson@arm.com
909179Sandreas.hansson@arm.com        // optimise for the common case and see if the tick should be
919179Sandreas.hansson@arm.com        // advanced by a single clock period
929793Sakash.bagdia@arm.com        tick += clockPeriod();
939179Sandreas.hansson@arm.com        ++cycle;
949179Sandreas.hansson@arm.com
959179Sandreas.hansson@arm.com        // see if we are done at this point
969179Sandreas.hansson@arm.com        if (tick >= curTick())
979179Sandreas.hansson@arm.com            return;
989179Sandreas.hansson@arm.com
999179Sandreas.hansson@arm.com        // if not, we have to recalculate the cycle and tick, we
1009179Sandreas.hansson@arm.com        // perform the calculations in terms of relative cycles to
1019179Sandreas.hansson@arm.com        // allow changes to the clock period in the future
1029793Sakash.bagdia@arm.com        Cycles elapsedCycles(divCeil(curTick() - tick, clockPeriod()));
1039179Sandreas.hansson@arm.com        cycle += elapsedCycles;
1049793Sakash.bagdia@arm.com        tick += elapsedCycles * clockPeriod();
1059179Sandreas.hansson@arm.com    }
1069179Sandreas.hansson@arm.com
1079793Sakash.bagdia@arm.com    /**
1089793Sakash.bagdia@arm.com     * The clock domain this clocked object belongs to
1099793Sakash.bagdia@arm.com     */
1109793Sakash.bagdia@arm.com    ClockDomain &clockDomain;
1119157Sandreas.hansson@arm.com
1129545Sandreas.hansson@arm.com  protected:
1139545Sandreas.hansson@arm.com
1149157Sandreas.hansson@arm.com    /**
1159793Sakash.bagdia@arm.com     * Create a clocked object and set the clock domain based on the
1169157Sandreas.hansson@arm.com     * parameters.
1179157Sandreas.hansson@arm.com     */
1189179Sandreas.hansson@arm.com    ClockedObject(const ClockedObjectParams* p) :
1199793Sakash.bagdia@arm.com        SimObject(p), tick(0), cycle(0), clockDomain(*p->clk_domain)
1209418Sandreas.hansson@arm.com    {
1219418Sandreas.hansson@arm.com    }
1229157Sandreas.hansson@arm.com
1239157Sandreas.hansson@arm.com    /**
1249157Sandreas.hansson@arm.com     * Virtual destructor due to inheritance.
1259157Sandreas.hansson@arm.com     */
1269157Sandreas.hansson@arm.com    virtual ~ClockedObject() { }
1279157Sandreas.hansson@arm.com
1289296Snilay@cs.wisc.edu    /**
1299296Snilay@cs.wisc.edu     * Reset the object's clock using the current global tick value. Likely
1309296Snilay@cs.wisc.edu     * to be used only when the global clock is reset. Currently, this done
1319296Snilay@cs.wisc.edu     * only when Ruby is done warming up the memory system.
1329296Snilay@cs.wisc.edu     */
1339296Snilay@cs.wisc.edu    void resetClock() const
1349296Snilay@cs.wisc.edu    {
1359793Sakash.bagdia@arm.com        Cycles elapsedCycles(divCeil(curTick(), clockPeriod()));
1369296Snilay@cs.wisc.edu        cycle = elapsedCycles;
1379793Sakash.bagdia@arm.com        tick = elapsedCycles * clockPeriod();
1389296Snilay@cs.wisc.edu    }
1399296Snilay@cs.wisc.edu
1409157Sandreas.hansson@arm.com  public:
1419157Sandreas.hansson@arm.com
1429157Sandreas.hansson@arm.com    /**
1439179Sandreas.hansson@arm.com     * Determine the tick when a cycle begins, by default the current
1449179Sandreas.hansson@arm.com     * one, but the argument also enables the caller to determine a
1459179Sandreas.hansson@arm.com     * future cycle.
1469179Sandreas.hansson@arm.com     *
1479179Sandreas.hansson@arm.com     * @param cycles The number of cycles into the future
1489179Sandreas.hansson@arm.com     *
1499179Sandreas.hansson@arm.com     * @return The tick when the clock edge occurs
1509179Sandreas.hansson@arm.com     */
1519180Sandreas.hansson@arm.com    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
1529179Sandreas.hansson@arm.com    {
1539179Sandreas.hansson@arm.com        // align tick to the next clock edge
1549179Sandreas.hansson@arm.com        update();
1559179Sandreas.hansson@arm.com
1569179Sandreas.hansson@arm.com        // figure out when this future cycle is
1579793Sakash.bagdia@arm.com        return tick + clockPeriod() * cycles;
1589179Sandreas.hansson@arm.com    }
1599179Sandreas.hansson@arm.com
1609179Sandreas.hansson@arm.com    /**
1619179Sandreas.hansson@arm.com     * Determine the current cycle, corresponding to a tick aligned to
1629179Sandreas.hansson@arm.com     * a clock edge.
1639179Sandreas.hansson@arm.com     *
1649180Sandreas.hansson@arm.com     * @return The current cycle count
1659179Sandreas.hansson@arm.com     */
1669180Sandreas.hansson@arm.com    inline Cycles curCycle() const
1679179Sandreas.hansson@arm.com    {
1689179Sandreas.hansson@arm.com        // align cycle to the next clock edge.
1699179Sandreas.hansson@arm.com        update();
1709179Sandreas.hansson@arm.com
1719179Sandreas.hansson@arm.com        return cycle;
1729179Sandreas.hansson@arm.com    }
1739179Sandreas.hansson@arm.com
1749179Sandreas.hansson@arm.com    /**
1759648Sdam.sunwoo@arm.com     * Based on the clock of the object, determine the tick when the next
1769648Sdam.sunwoo@arm.com     * cycle begins, in other words, return the next clock edge.
1779648Sdam.sunwoo@arm.com     * (This can never be the current tick.)
1789157Sandreas.hansson@arm.com     *
1799157Sandreas.hansson@arm.com     * @return The tick when the next cycle starts
1809157Sandreas.hansson@arm.com     */
1819157Sandreas.hansson@arm.com    Tick nextCycle() const
1829648Sdam.sunwoo@arm.com    { return clockEdge(Cycles(1)); }
1839157Sandreas.hansson@arm.com
1849793Sakash.bagdia@arm.com    inline uint64_t frequency() const
1859793Sakash.bagdia@arm.com    {
1869793Sakash.bagdia@arm.com        return SimClock::Frequency / clockPeriod();
1879793Sakash.bagdia@arm.com    }
1889157Sandreas.hansson@arm.com
1899793Sakash.bagdia@arm.com    inline Tick clockPeriod() const
1909793Sakash.bagdia@arm.com    {
1919793Sakash.bagdia@arm.com        return clockDomain.clockPeriod();
1929793Sakash.bagdia@arm.com    }
1939157Sandreas.hansson@arm.com
1949550Sandreas.hansson@arm.com    inline Cycles ticksToCycles(Tick t) const
1959793Sakash.bagdia@arm.com    { return Cycles(t / clockPeriod()); }
1969157Sandreas.hansson@arm.com
1979157Sandreas.hansson@arm.com};
1989157Sandreas.hansson@arm.com
1999157Sandreas.hansson@arm.com#endif //__SIM_CLOCKED_OBJECT_HH__
200