clocked_object.hh revision 9648:f10eb34e3e38
12SN/A/*
21762SN/A * Copyright (c) 2012 ARM Limited
32SN/A * All rights reserved
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Redistribution and use in source and binary forms, with or without
152SN/A * modification, are permitted provided that the following conditions are
162SN/A * met: redistributions of source code must retain the above copyright
172SN/A * notice, this list of conditions and the following disclaimer;
182SN/A * redistributions in binary form must reproduce the above copyright
192SN/A * notice, this list of conditions and the following disclaimer in the
202SN/A * documentation and/or other materials provided with the distribution;
212SN/A * neither the name of the copyright holders nor the names of its
222SN/A * contributors may be used to endorse or promote products derived from
232SN/A * this software without specific prior written permission.
242SN/A *
252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262SN/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
292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
313877Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
323877Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332147SN/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 "base/misc.hh"
502SN/A#include "params/ClockedObject.hh"
512SN/A#include "sim/core.hh"
522SN/A#include "sim/sim_object.hh"
531078SN/A
542SN/A/**
552SN/A * The ClockedObject class extends the SimObject with a clock and
561114SN/A * accessor functions to relate ticks to the cycles of the object.
571114SN/A */
582SN/Aclass ClockedObject : public SimObject
592SN/A{
602SN/A
612SN/A  private:
621114SN/A
631114SN/A    // the tick value of the next clock edge (>= curTick()) at the
642SN/A    // time of the last call to update()
652SN/A    mutable Tick tick;
662SN/A
671114SN/A    // The cycle counter value corresponding to the current value of
681114SN/A    // 'tick'
691114SN/A    mutable Cycles cycle;
701114SN/A
711114SN/A    /**
721114SN/A     * Prevent inadvertent use of the copy constructor and assignment
731114SN/A     * operator by making them private.
741114SN/A     */
751114SN/A    ClockedObject(ClockedObject&);
762SN/A    ClockedObject& operator=(ClockedObject&);
772SN/A
783877Sbinkertn@umich.edu    /**
792SN/A     *  Align cycle and tick to the next clock edge if not already done.
80502SN/A     */
812SN/A    void update() const
822SN/A    {
832SN/A        // both tick and cycle are up-to-date and we are done, note
842SN/A        // that the >= is important as it captures cases where tick
852SN/A        // has already passed curTick()
862SN/A        if (tick >= curTick())
872SN/A            return;
882SN/A
892SN/A        // optimise for the common case and see if the tick should be
902SN/A        // advanced by a single clock period
913877Sbinkertn@umich.edu        tick += clock;
923877Sbinkertn@umich.edu        ++cycle;
931114SN/A
942SN/A        // see if we are done at this point
952SN/A        if (tick >= curTick())
962SN/A            return;
972SN/A
982SN/A        // if not, we have to recalculate the cycle and tick, we
992SN/A        // perform the calculations in terms of relative cycles to
1002SN/A        // allow changes to the clock period in the future
1012SN/A        Cycles elapsedCycles(divCeil(curTick() - tick, clock));
1022SN/A        cycle += elapsedCycles;
1032SN/A        tick += elapsedCycles * clock;
1042SN/A    }
1052SN/A
1062SN/A    // Clock period in ticks
1072SN/A    Tick clock;
1082SN/A
1092SN/A  protected:
1102SN/A
1112SN/A    /**
1122SN/A     * Create a clocked object and set the clock based on the
1132SN/A     * parameters.
1142SN/A     */
1152SN/A    ClockedObject(const ClockedObjectParams* p) :
1162SN/A        SimObject(p), tick(0), cycle(0), clock(p->clock)
1172SN/A    {
1182SN/A        if (clock == 0) {
1192SN/A            fatal("%s has a clock period of zero\n", name());
1202SN/A        }
1212SN/A    }
1222SN/A
1233877Sbinkertn@umich.edu    /**
124     * Virtual destructor due to inheritance.
125     */
126    virtual ~ClockedObject() { }
127
128    /**
129     * Reset the object's clock using the current global tick value. Likely
130     * to be used only when the global clock is reset. Currently, this done
131     * only when Ruby is done warming up the memory system.
132     */
133    void resetClock() const
134    {
135        Cycles elapsedCycles(divCeil(curTick(), clock));
136        cycle = elapsedCycles;
137        tick = elapsedCycles * clock;
138    }
139
140  public:
141
142    /**
143     * Determine the tick when a cycle begins, by default the current
144     * one, but the argument also enables the caller to determine a
145     * future cycle.
146     *
147     * @param cycles The number of cycles into the future
148     *
149     * @return The tick when the clock edge occurs
150     */
151    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
152    {
153        // align tick to the next clock edge
154        update();
155
156        // figure out when this future cycle is
157        return tick + clock * cycles;
158    }
159
160    /**
161     * Determine the current cycle, corresponding to a tick aligned to
162     * a clock edge.
163     *
164     * @return The current cycle count
165     */
166    inline Cycles curCycle() const
167    {
168        // align cycle to the next clock edge.
169        update();
170
171        return cycle;
172    }
173
174    /**
175     * Based on the clock of the object, determine the tick when the next
176     * cycle begins, in other words, return the next clock edge.
177     * (This can never be the current tick.)
178     *
179     * @return The tick when the next cycle starts
180     */
181    Tick nextCycle() const
182    { return clockEdge(Cycles(1)); }
183
184    inline uint64_t frequency() const { return SimClock::Frequency / clock; }
185
186    inline Tick clockPeriod() const { return clock; }
187
188    inline Cycles ticksToCycles(Tick t) const
189    { return Cycles(t / clock); }
190
191};
192
193#endif //__SIM_CLOCKED_OBJECT_HH__
194