clocked_object.hh revision 9179:666bc9df1e49
172SN/A/*
21762SN/A * Copyright (c) 2012 ARM Limited
372SN/A * All rights reserved
472SN/A *
572SN/A * The license below extends only to copyright in the software and shall
672SN/A * not be construed as granting a license to any other intellectual
772SN/A * property including but not limited to intellectual property relating
872SN/A * to a hardware implementation of the functionality of the software
972SN/A * licensed hereunder.  You may use the software subject to the license
1072SN/A * terms below provided that you ensure that this notice is replicated
1172SN/A * unmodified and in its entirety in all distributions of the software,
1272SN/A * modified or unmodified, in source code or in binary form.
1372SN/A *
1472SN/A * Redistribution and use in source and binary forms, with or without
1572SN/A * modification, are permitted provided that the following conditions are
1672SN/A * met: redistributions of source code must retain the above copyright
1772SN/A * notice, this list of conditions and the following disclaimer;
1872SN/A * redistributions in binary form must reproduce the above copyright
1972SN/A * notice, this list of conditions and the following disclaimer in the
2072SN/A * documentation and/or other materials provided with the distribution;
2172SN/A * neither the name of the copyright holders nor the names of its
2272SN/A * contributors may be used to endorse or promote products derived from
2372SN/A * this software without specific prior written permission.
2472SN/A *
2572SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2672SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2972SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3072SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362SN/A *
372SN/A * Authors: Andreas Hansson
382SN/A */
392SN/A
402SN/A/**
412SN/A * @file
422SN/A * ClockedObject declaration and implementation.
432SN/A */
442SN/A
452SN/A#ifndef __SIM_CLOCKED_OBJECT_HH__
462SN/A#define __SIM_CLOCKED_OBJECT_HH__
472SN/A
482SN/A#include "base/intmath.hh"
492SN/A#include "params/ClockedObject.hh"
502SN/A#include "sim/sim_object.hh"
512SN/A
522SN/A/**
532SN/A * The ClockedObject class extends the SimObject with a clock and
542SN/A * accessor functions to relate ticks to the cycles of the object.
552SN/A */
562SN/Aclass ClockedObject : public SimObject
572SN/A{
582SN/A
592SN/A  private:
602SN/A
612SN/A    // the tick value of the next clock edge (>= curTick()) at the
622SN/A    // time of the last call to update()
632SN/A    mutable Tick tick;
642SN/A
652SN/A    // The cycle counter value corresponding to the current value of
662SN/A    // 'tick'
672SN/A    mutable Tick cycle;
682SN/A
692SN/A    /**
702SN/A     * Prevent inadvertent use of the copy constructor and assignment
712SN/A     * operator by making them private.
722SN/A     */
732SN/A    ClockedObject(ClockedObject&);
742SN/A    ClockedObject& operator=(ClockedObject&);
752SN/A
762SN/A    /**
772SN/A     *  Align cycle and tick to the next clock edge if not already done.
782SN/A     */
792SN/A    void update() const
802SN/A    {
812SN/A        // both tick and cycle are up-to-date and we are done, note
822SN/A        // that the >= is important as it captures cases where tick
832SN/A        // has already passed curTick()
842SN/A        if (tick >= curTick())
852SN/A            return;
862SN/A
872SN/A        // optimise for the common case and see if the tick should be
882SN/A        // advanced by a single clock period
892SN/A        tick += clock;
902SN/A        ++cycle;
912SN/A
922SN/A        // see if we are done at this point
932SN/A        if (tick >= curTick())
942SN/A            return;
952SN/A
962SN/A        // if not, we have to recalculate the cycle and tick, we
972SN/A        // perform the calculations in terms of relative cycles to
982SN/A        // allow changes to the clock period in the future
992SN/A        Tick elapsedCycles = divCeil(curTick() - tick, clock);
1002SN/A        cycle += elapsedCycles;
1012SN/A        tick += elapsedCycles * clock;
1022SN/A    }
1032SN/A
1042SN/A  protected:
1052SN/A
1062SN/A    // Clock period in ticks
1072SN/A    Tick clock;
1082SN/A
1092SN/A    /**
1102SN/A     * Create a clocked object and set the clock based on the
1112SN/A     * parameters.
1122SN/A     */
1132SN/A    ClockedObject(const ClockedObjectParams* p) :
1142SN/A        SimObject(p), tick(0), cycle(0), clock(p->clock)
1152SN/A    { }
1162SN/A
1172SN/A    /**
1182SN/A     * Virtual destructor due to inheritance.
1192SN/A     */
1202SN/A    virtual ~ClockedObject() { }
1211717SN/A
1222SN/A  public:
1232SN/A
1243960Sgblack@eecs.umich.edu    /**
1253960Sgblack@eecs.umich.edu     * Determine the tick when a cycle begins, by default the current
1263960Sgblack@eecs.umich.edu     * one, but the argument also enables the caller to determine a
1272521SN/A     * future cycle.
1283960Sgblack@eecs.umich.edu     *
1293960Sgblack@eecs.umich.edu     * @param cycles The number of cycles into the future
13056SN/A     *
13156SN/A     * @return The tick when the clock edge occurs
13256SN/A     */
13356SN/A    inline Tick clockEdge(int cycles = 0) const
1342680Sktlim@umich.edu    {
1351717SN/A        // align tick to the next clock edge
1363960Sgblack@eecs.umich.edu        update();
1372521SN/A
1383960Sgblack@eecs.umich.edu        // figure out when this future cycle is
1391717SN/A        return tick + ticks(cycles);
1402SN/A    }
1412SN/A
1422107SN/A    /**
1432SN/A     * Determine the current cycle, corresponding to a tick aligned to
1442009SN/A     * a clock edge.
1453536Sgblack@eecs.umich.edu     *
1462SN/A     * @return The current cycle
1472SN/A     */
1482SN/A    inline Tick curCycle() const
1492SN/A    {
1503536Sgblack@eecs.umich.edu        // align cycle to the next clock edge.
1511910SN/A        update();
1523536Sgblack@eecs.umich.edu
1531910SN/A        return cycle;
1541910SN/A    }
1551910SN/A
1563536Sgblack@eecs.umich.edu    /**
1571910SN/A     * Based on the clock of the object, determine the tick when the
1582SN/A     * next cycle begins, in other words, return the next clock edge.
1592SN/A     *
1602SN/A     * @return The tick when the next cycle starts
1612SN/A     */
1622SN/A    Tick nextCycle() const
1632SN/A    { return clockEdge(); }
1642SN/A
1652SN/A    inline Tick frequency() const { return SimClock::Frequency / clock; }
1662SN/A
1672SN/A    inline Tick ticks(int cycles) const { return clock * cycles; }
1682SN/A
1692SN/A    inline Tick clockPeriod() const { return clock; }
1702SN/A
1712SN/A    inline Tick tickToCycle(Tick tick) const { return tick / clock; }
1722SN/A
1732SN/A};
1742SN/A
1752SN/A#endif //__SIM_CLOCKED_OBJECT_HH__
1763536Sgblack@eecs.umich.edu