diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index b418a7489..906903b8b 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -619,7 +619,6 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) X86ISA::Interrupts::Interrupts(Params * p) : BasicPioDevice(p), IntDev(this, p->int_latency), latency(p->pio_latency), - clock(0), apicTimerEvent(this), pendingSmi(false), smiVector(0), pendingNmi(false), nmiVector(0), @@ -630,6 +629,8 @@ X86ISA::Interrupts::Interrupts(Params * p) : pendingIPIs(0), cpu(NULL), intSlavePort(name() + ".int_slave", this, this, latency) { + // Override the default clock + clock = 0; pioSize = PageBytes; memset(regs, 0, sizeof(regs)); //Set the local apic DFR to the flat model. diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 1b7f5a52c..06425fbda 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -89,7 +89,6 @@ class Interrupts : public BasicPioDevice, IntDev * Timing related stuff. */ Tick latency; - Tick clock; class ApicTimerEvent : public Event { diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index 678467672..acca97c49 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -173,7 +173,9 @@ void initCPU(ThreadContext *tc, int cpuId) interrupts->setRegNoEffect(APIC_ID, cpuId << 24); interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14); - + + // @todo: Control the relative frequency, in this case 16:1, of + // the clocks in the Python code interrupts->setClock(tc->getCpuPtr()->ticks(16)); // TODO Set the SMRAM base address (SMBASE) to 0x00030000 diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 9ed2cb789..8c658b196 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -145,9 +145,6 @@ class BaseCPU(MemObject): defer_registration = Param.Bool(False, "defer registration with system (for sampling)") - clock = Param.Clock('1t', "clock speed") - phase = Param.Latency('0ns', "clock phase") - tracer = Param.InstTracer(default_tracer, "Instruction tracer") icache_port = MasterPort("Instruction Port") diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 893b0e06b..c1b1e6d36 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -115,15 +115,12 @@ CPUProgressEvent::description() const } BaseCPU::BaseCPU(Params *p, bool is_checker) - : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), + : MemObject(p), instCnt(0), _cpuId(p->cpu_id), _instMasterId(p->system->getMasterId(name() + ".inst")), _dataMasterId(p->system->getMasterId(name() + ".data")), interrupts(p->interrupts), - numThreads(p->numThreads), system(p->system), - phase(p->phase) + numThreads(p->numThreads), system(p->system) { -// currentTick = curTick(); - // if Python did not provide a valid ID, do it here if (_cpuId == -1 ) { _cpuId = cpuList.size(); @@ -317,27 +314,6 @@ BaseCPU::getMasterPort(const string &if_name, int idx) return MemObject::getMasterPort(if_name, idx); } -Tick -BaseCPU::nextCycle() -{ - Tick next_tick = curTick() - phase + clock - 1; - next_tick -= (next_tick % clock); - next_tick += phase; - return next_tick; -} - -Tick -BaseCPU::nextCycle(Tick begin_tick) -{ - Tick next_tick = begin_tick; - if (next_tick % clock != 0) - next_tick = next_tick - (next_tick % clock) + clock; - next_tick += phase; - - assert(next_tick >= curTick()); - return next_tick; -} - void BaseCPU::registerThreadContexts() { diff --git a/src/cpu/base.hh b/src/cpu/base.hh index b99b25d17..aab6ac4ca 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -88,8 +88,7 @@ class CPUProgressEvent : public Event class BaseCPU : public MemObject { protected: - // CPU's clock period in terms of the number of ticks of curTime. - Tick clock; + // @todo remove me after debugging with legion done Tick instCnt; // every cpu has an id, put it in the base cpu @@ -174,30 +173,11 @@ class BaseCPU : public MemObject */ MasterPort &getMasterPort(const std::string &if_name, int idx = -1); -// Tick currentTick; - inline Tick frequency() const { return SimClock::Frequency / clock; } - inline Tick ticks(int numCycles) const { return clock * numCycles; } - inline Tick curCycle() const { return curTick() / clock; } - inline Tick tickToCycles(Tick val) const { return val / clock; } inline void workItemBegin() { numWorkItemsStarted++; } inline void workItemEnd() { numWorkItemsCompleted++; } // @todo remove me after debugging with legion done Tick instCount() { return instCnt; } - /** The next cycle the CPU should be scheduled, given a cache - * access or quiesce event returning on this cycle. This function - * may return curTick() if the CPU should run on the current cycle. - */ - Tick nextCycle(); - - /** The next cycle the CPU should be scheduled, given a cache - * access or quiesce event returning on the given Tick. This - * function may return curTick() if the CPU should run on the - * current cycle. - * @param begin_tick The tick that the event is completing on. - */ - Tick nextCycle(Tick begin_tick); - TheISA::MicrocodeRom microcodeRom; protected: @@ -328,8 +308,6 @@ class BaseCPU : public MemObject System *system; - Tick phase; - /** * Serialize this object to the given output stream. * @param os The stream to serialize to. diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh index 52e32d72d..94617c876 100644 --- a/src/cpu/testers/memtest/memtest.hh +++ b/src/cpu/testers/memtest/memtest.hh @@ -56,8 +56,6 @@ class MemTest : public MemObject // register statistics virtual void regStats(); - inline Tick ticks(int numCycles) const { return numCycles; } - // main simulation loop (one cycle) void tick(); diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/networktest/networktest.hh index aec74a484..76119e678 100644 --- a/src/cpu/testers/networktest/networktest.hh +++ b/src/cpu/testers/networktest/networktest.hh @@ -51,8 +51,6 @@ class NetworkTest : public MemObject virtual void init(); - inline Tick ticks(int numCycles) const { return numCycles; } - // main simulation loop (one cycle) void tick(); diff --git a/src/dev/CopyEngine.py b/src/dev/CopyEngine.py index b89486be8..9aa0e1fe5 100644 --- a/src/dev/CopyEngine.py +++ b/src/dev/CopyEngine.py @@ -52,8 +52,8 @@ class CopyEngine(PciDevice): ChanCnt = Param.UInt8(4, "Number of DMA channels that exist on device") XferCap = Param.MemorySize('4kB', "Number of bits of transfer size that are supported") - - clock = Param.Clock('500MHz', "Clock speed of the device") + # Override the default clock + clock = '500MHz' latBeforeBegin = Param.Latency('20ns', "Latency after a DMA command is seen before it's proccessed") latAfterCompletion = Param.Latency('20ns', "Latency after a DMA command is complete before it's reported as such") diff --git a/src/dev/Ethernet.py b/src/dev/Ethernet.py index 91d4e230e..1afbce8ee 100644 --- a/src/dev/Ethernet.py +++ b/src/dev/Ethernet.py @@ -79,7 +79,8 @@ class IGbE(EtherDevice): "Number of enteries in the rx descriptor cache") tx_desc_cache_size = Param.Int(64, "Number of enteries in the rx descriptor cache") - clock = Param.Clock('500MHz', "Clock speed of the device") + # Override the default clock + clock = '500MHz' VendorID = 0x8086 SubsystemID = 0x1008 SubsystemVendorID = 0x8086 @@ -127,7 +128,8 @@ class EtherDevBase(EtherDevice): hardware_address = Param.EthernetAddr(NextEthernetAddr, "Ethernet Hardware Address") - clock = Param.Clock('0ns', "State machine processor frequency") + # Override the default clock + clock = '0ns' dma_read_delay = Param.Latency('0us', "fixed delay for dma reads") dma_read_factor = Param.Latency('0us', "multiplier for dma reads") diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 967267197..876188c12 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -118,7 +118,8 @@ class CpuLocalTimer(BasicPioDevice): gic = Param.Gic(Parent.any, "Gic to use for interrupting") int_num_timer = Param.UInt32("Interrrupt number used per-cpu to GIC") int_num_watchdog = Param.UInt32("Interrupt number for per-cpu watchdog to GIC") - clock = Param.Clock('1GHz', "Clock speed at which the timer counts") + # Override the default clock + clock = '1GHz' class PL031(AmbaIntDevice): type = 'PL031' @@ -134,7 +135,8 @@ class Pl050(AmbaIntDevice): class Pl111(AmbaDmaDevice): type = 'Pl111' - clock = Param.Clock('24MHz', "Clock speed of the input") + # Override the default clock + clock = '24MHz' vnc = Param.VncServer(Parent.any, "Vnc server for remote frame buffer display") amba_id = 0x00141111 diff --git a/src/dev/arm/pl111.cc b/src/dev/arm/pl111.cc index 998644a8c..d79a1cf39 100644 --- a/src/dev/arm/pl111.cc +++ b/src/dev/arm/pl111.cc @@ -63,7 +63,7 @@ Pl111::Pl111(const Params *p) lcdRis(0), lcdMis(0), clcdCrsrCtrl(0), clcdCrsrConfig(0), clcdCrsrPalette0(0), clcdCrsrPalette1(0), clcdCrsrXY(0), clcdCrsrClip(0), clcdCrsrImsc(0), - clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0), clock(p->clock), + clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0), vncserver(p->vnc), bmp(NULL), width(LcdMaxWidth), height(LcdMaxHeight), bytesPerPixel(4), startTime(0), startAddr(0), maxAddr(0), curAddr(0), waterMark(0), dmaPendingNum(0), readEvent(this), fillFifoEvent(this), @@ -512,26 +512,6 @@ Pl111::dmaDone() schedule(fillFifoEvent, nextCycle()); } - -Tick -Pl111::nextCycle() -{ - Tick nextTick = curTick() + clock - 1; - nextTick -= nextTick%clock; - return nextTick; -} - -Tick -Pl111::nextCycle(Tick beginTick) -{ - Tick nextTick = beginTick; - if (nextTick%clock!=0) - nextTick = nextTick - (nextTick%clock) + clock; - - assert(nextTick >= curTick()); - return nextTick; -} - void Pl111::serialize(std::ostream &os) { @@ -586,7 +566,6 @@ Pl111::serialize(std::ostream &os) uint8_t clcdCrsrMis_serial = clcdCrsrMis; SERIALIZE_SCALAR(clcdCrsrMis_serial); - SERIALIZE_SCALAR(clock); SERIALIZE_SCALAR(height); SERIALIZE_SCALAR(width); SERIALIZE_SCALAR(bytesPerPixel); @@ -689,7 +668,6 @@ Pl111::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(clcdCrsrMis_serial); clcdCrsrMis = clcdCrsrMis_serial; - UNSERIALIZE_SCALAR(clock); UNSERIALIZE_SCALAR(height); UNSERIALIZE_SCALAR(width); UNSERIALIZE_SCALAR(bytesPerPixel); diff --git a/src/dev/arm/pl111.hh b/src/dev/arm/pl111.hh index c4fb84efa..599d4fa3e 100644 --- a/src/dev/arm/pl111.hh +++ b/src/dev/arm/pl111.hh @@ -228,9 +228,6 @@ class Pl111: public AmbaDmaDevice /** Cursor masked interrupt status register - const */ InterruptReg clcdCrsrMis; - /** Clock speed */ - Tick clock; - /** VNC server */ VncServer *vncserver; @@ -291,10 +288,6 @@ class Pl111: public AmbaDmaDevice /** DMA done event */ void dmaDone(); - /** Next cycle event */ - Tick nextCycle(); - Tick nextCycle(Tick beginTick); - /** DMA framebuffer read event */ EventWrapper readEvent; diff --git a/src/dev/arm/timer_cpulocal.cc b/src/dev/arm/timer_cpulocal.cc index 97d3c5883..097c52186 100644 --- a/src/dev/arm/timer_cpulocal.cc +++ b/src/dev/arm/timer_cpulocal.cc @@ -58,7 +58,7 @@ CpuLocalTimer::CpuLocalTimer(Params *p) localTimer[i].parent = this; localTimer[i].intNumTimer = p->int_num_timer; localTimer[i].intNumWatchdog = p->int_num_watchdog; - localTimer[i].clock = p->clock; + localTimer[i].clock = clock; localTimer[i].cpuNum = i; } pioSize = 0x38; @@ -339,7 +339,6 @@ CpuLocalTimer::Timer::serialize(std::ostream &os) DPRINTF(Checkpoint, "Serializing Arm CpuLocalTimer\n"); SERIALIZE_SCALAR(intNumTimer); SERIALIZE_SCALAR(intNumWatchdog); - SERIALIZE_SCALAR(clock); uint32_t timer_control_serial = timerControl; uint32_t watchdog_control_serial = watchdogControl; @@ -379,7 +378,6 @@ CpuLocalTimer::Timer::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(intNumTimer); UNSERIALIZE_SCALAR(intNumWatchdog); - UNSERIALIZE_SCALAR(clock); uint32_t timer_control_serial; UNSERIALIZE_SCALAR(timer_control_serial); diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index 14d767288..f7f6a1178 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -68,7 +68,7 @@ IGbE::IGbE(const Params *p) tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this), rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size), txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size), - clock(p->clock), lastInterrupt(0) + lastInterrupt(0) { etherInt = new IGbEInt(name() + ".int", this); diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh index a6b20a2bf..099cd0d11 100644 --- a/src/dev/i8254xGBe.hh +++ b/src/dev/i8254xGBe.hh @@ -523,9 +523,7 @@ class IGbE : public EtherDevice virtual EtherInt *getEthPort(const std::string &if_name, int idx); - Tick clock; Tick lastInterrupt; - inline Tick ticks(int numCycles) const { return numCycles * clock; } virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index 4a459c6c6..6a55516c5 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -99,7 +99,6 @@ NSGigE::NSGigE(Params *p) txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false), - clock(p->clock), txState(txIdle), txEnable(false), CTDD(false), txHalt(false), txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false), diff --git a/src/dev/ns_gige.hh b/src/dev/ns_gige.hh index 87cf56962..8032c0623 100644 --- a/src/dev/ns_gige.hh +++ b/src/dev/ns_gige.hh @@ -196,10 +196,6 @@ class NSGigE : public EtherDevice ns_desc64 txDesc64; ns_desc64 rxDesc64; - /* state machine cycle time */ - Tick clock; - inline Tick ticks(int numCycles) const { return numCycles * clock; } - /* tx State Machine */ TxState txState; bool txEnable; diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index 1030e1a9c..623dcf2c1 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -78,7 +78,7 @@ const char *TxStateStrings[] = // Sinic PCI Device // Base::Base(const Params *p) - : PciDev(p), rxEnable(false), txEnable(false), clock(p->clock), + : PciDev(p), rxEnable(false), txEnable(false), intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false), cpuPendingIntr(false), intrEvent(0), interface(NULL) { diff --git a/src/dev/sinic.hh b/src/dev/sinic.hh index 0da7ccae4..5532650c3 100644 --- a/src/dev/sinic.hh +++ b/src/dev/sinic.hh @@ -50,8 +50,6 @@ class Base : public PciDev protected: bool rxEnable; bool txEnable; - Tick clock; - inline Tick ticks(int numCycles) const { return numCycles * clock; } protected: Tick intrDelay; diff --git a/src/mem/Bus.py b/src/mem/Bus.py index 12657e177..b398af959 100644 --- a/src/mem/Bus.py +++ b/src/mem/Bus.py @@ -47,7 +47,8 @@ class BaseBus(MemObject): abstract = True slave = VectorSlavePort("vector port for connecting masters") master = VectorMasterPort("vector port for connecting slaves") - clock = Param.Clock("1GHz", "bus clock speed") + # Override the default clock + clock = '1GHz' header_cycles = Param.Int(1, "cycles of overhead per transaction") width = Param.Int(8, "bus width (bytes)") block_size = Param.Int(64, "The default block size if not set by " \ diff --git a/src/mem/MemObject.py b/src/mem/MemObject.py index e2e858494..0f33cc0bf 100644 --- a/src/mem/MemObject.py +++ b/src/mem/MemObject.py @@ -26,8 +26,8 @@ # # Authors: Ron Dreslinski -from m5.SimObject import SimObject +from ClockedObject import ClockedObject -class MemObject(SimObject): +class MemObject(ClockedObject): type = 'MemObject' abstract = True diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 583e60a15..829d694de 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -47,7 +47,6 @@ * Definition of a bus object. */ -#include "base/intmath.hh" #include "base/misc.hh" #include "base/trace.hh" #include "debug/Bus.hh" @@ -56,7 +55,7 @@ #include "mem/bus.hh" BaseBus::BaseBus(const BaseBusParams *p) - : MemObject(p), clock(p->clock), + : MemObject(p), headerCycles(p->header_cycles), width(p->width), defaultPortID(InvalidPortID), useDefaultRange(p->use_default_range), @@ -114,7 +113,7 @@ BaseBus::calcPacketTiming(PacketPtr pkt) { // determine the current time rounded to the closest following // clock edge - Tick now = divCeil(curTick(), clock) * clock; + Tick now = nextCycle(); Tick headerTime = now + headerCycles * clock; @@ -287,7 +286,7 @@ BaseBus::Layer::retryWaiting() // determine the current time rounded to the closest following // clock edge - Tick now = divCeil(curTick(), clock) * clock; + Tick now = bus.nextCycle(); occupyLayer(now + clock); } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index d4c3b4724..ac35581b1 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -228,8 +228,6 @@ class BaseBus : public MemObject }; - /** the clock speed for the bus */ - Tick clock; /** cycles of overhead per transaction */ int headerCycles; /** the width of the bus in bytes */ diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc index ce8badbe7..cc05b7fc2 100644 --- a/src/mem/mem_object.cc +++ b/src/mem/mem_object.cc @@ -44,7 +44,7 @@ #include "mem/mem_object.hh" MemObject::MemObject(const Params *params) - : SimObject(params) + : ClockedObject(params) { } diff --git a/src/mem/mem_object.hh b/src/mem/mem_object.hh index d8e6bdcb0..6cc0c4fd3 100644 --- a/src/mem/mem_object.hh +++ b/src/mem/mem_object.hh @@ -51,13 +51,13 @@ #include "mem/port.hh" #include "params/MemObject.hh" -#include "sim/sim_object.hh" +#include "sim/clocked_object.hh" /** - * The MemObject class extends the SimObject with accessor functions + * The MemObject class extends the ClockedObject with accessor functions * to get its master and slave ports. */ -class MemObject : public SimObject +class MemObject : public ClockedObject { public: typedef MemObjectParams Params; diff --git a/src/sim/ClockedObject.py b/src/sim/ClockedObject.py new file mode 100644 index 000000000..9bb243df8 --- /dev/null +++ b/src/sim/ClockedObject.py @@ -0,0 +1,45 @@ +# Copyright (c) 2012 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Andreas Hansson + +from m5.SimObject import SimObject +from m5.params import * + +class ClockedObject(SimObject): + type = 'ClockedObject' + abstract = True + + clock = Param.Clock('1t', "Clock speed") diff --git a/src/sim/SConscript b/src/sim/SConscript index 9f76d6381..16eeb36d3 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -31,6 +31,7 @@ Import('*') SimObject('BaseTLB.py') +SimObject('ClockedObject.py') SimObject('Root.py') SimObject('InstTracer.py') diff --git a/src/sim/clocked_object.hh b/src/sim/clocked_object.hh new file mode 100644 index 000000000..8ab637772 --- /dev/null +++ b/src/sim/clocked_object.hh @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Andreas Hansson + */ + +/** + * @file + * ClockedObject declaration and implementation. + */ + +#ifndef __SIM_CLOCKED_OBJECT_HH__ +#define __SIM_CLOCKED_OBJECT_HH__ + +#include "base/intmath.hh" +#include "params/ClockedObject.hh" +#include "sim/sim_object.hh" + +/** + * The ClockedObject class extends the SimObject with a clock and + * accessor functions to relate ticks to the cycles of the object. + */ +class ClockedObject : public SimObject +{ + + private: + + /** + * Prevent inadvertent use of the copy constructor and assignment + * operator by making them private. + */ + ClockedObject(ClockedObject&); + ClockedObject& operator=(ClockedObject&); + + protected: + + // Clock period in ticks + Tick clock; + + /** + * Create a clocked object and set the clock based on the + * parameters. + */ + ClockedObject(const ClockedObjectParams* p) : SimObject(p), clock(p->clock) + { } + + /** + * Virtual destructor due to inheritance. + */ + virtual ~ClockedObject() { } + + public: + + /** + * Based on the clock of the object, determine the tick when the + * next cycle begins, in other words, round the curTick() to the + * next tick that is a multiple of the clock. + * + * @return The tick when the next cycle starts + */ + Tick nextCycle() const + { return divCeil(curTick(), clock) * clock; } + + /** + * Determine the next cycle starting from a given tick instead of + * curTick(). + * + * @param begin_tick The tick to round to a clock edge + * + * @return The tick when the cycle after or on begin_tick starts + */ + Tick nextCycle(Tick begin_tick) const + { return divCeil(begin_tick, clock) * clock; } + + inline Tick frequency() const { return SimClock::Frequency / clock; } + + inline Tick ticks(int numCycles) const { return clock * numCycles; } + + inline Tick curCycle() const { return curTick() / clock; } + + inline Tick tickToCycles(Tick val) const { return val / clock; } + +}; + +#endif //__SIM_CLOCKED_OBJECT_HH__