summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/interrupts.cc3
-rw-r--r--src/arch/x86/interrupts.hh1
-rw-r--r--src/arch/x86/utility.cc4
-rw-r--r--src/cpu/BaseCPU.py3
-rw-r--r--src/cpu/base.cc28
-rw-r--r--src/cpu/base.hh24
-rw-r--r--src/cpu/testers/memtest/memtest.hh2
-rw-r--r--src/cpu/testers/networktest/networktest.hh2
-rw-r--r--src/dev/CopyEngine.py4
-rw-r--r--src/dev/Ethernet.py6
-rw-r--r--src/dev/arm/RealView.py6
-rw-r--r--src/dev/arm/pl111.cc24
-rw-r--r--src/dev/arm/pl111.hh7
-rw-r--r--src/dev/arm/timer_cpulocal.cc4
-rw-r--r--src/dev/i8254xGBe.cc2
-rw-r--r--src/dev/i8254xGBe.hh2
-rw-r--r--src/dev/ns_gige.cc1
-rw-r--r--src/dev/ns_gige.hh4
-rw-r--r--src/dev/sinic.cc2
-rw-r--r--src/dev/sinic.hh2
-rw-r--r--src/mem/Bus.py3
-rw-r--r--src/mem/MemObject.py4
-rw-r--r--src/mem/bus.cc7
-rw-r--r--src/mem/bus.hh2
-rw-r--r--src/mem/mem_object.cc2
-rw-r--r--src/mem/mem_object.hh6
-rw-r--r--src/sim/ClockedObject.py45
-rw-r--r--src/sim/SConscript1
-rw-r--r--src/sim/clocked_object.hh118
29 files changed, 197 insertions, 122 deletions
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 &section)
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<Pl111, &Pl111::readFramebuffer> 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 &section)
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<PortClass>::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__