From 7cd49b24d2523eaf21179946e291c46c6acf5bfc Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 19 Feb 2013 05:56:06 -0500 Subject: [PATCH] sim: Make clock private and access using clockPeriod() This patch makes the clock member private to the ClockedObject and forces all children to access it using clockPeriod(). This makes it impossible to inadvertently change the clock, and also makes it easier to transition to a situation where the clock is derived from e.g. a clock domain, or through a multiplier. --- src/dev/arm/timer_cpulocal.cc | 22 ++++++++------ src/dev/arm/timer_cpulocal.hh | 3 -- src/mem/bus.cc | 37 ++++++++++-------------- src/mem/bus.hh | 8 ++--- src/mem/cache/cache_impl.hh | 10 ++++--- src/mem/cache/prefetch/base.cc | 2 +- src/mem/coherent_bus.cc | 6 ++-- src/mem/coherent_bus.hh | 2 +- src/mem/noncoherent_bus.cc | 6 ++-- src/mem/noncoherent_bus.hh | 2 +- src/mem/ruby/system/RubyMemoryControl.cc | 4 +-- src/sim/clocked_object.hh | 4 +-- 12 files changed, 49 insertions(+), 57 deletions(-) diff --git a/src/dev/arm/timer_cpulocal.cc b/src/dev/arm/timer_cpulocal.cc index 84bc12aa9..458df0674 100644 --- a/src/dev/arm/timer_cpulocal.cc +++ b/src/dev/arm/timer_cpulocal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2011 ARM Limited + * Copyright (c) 2010-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -58,7 +58,6 @@ 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 = clock; localTimer[i].cpuNum = i; } pioSize = 0x38; @@ -104,9 +103,11 @@ CpuLocalTimer::Timer::read(PacketPtr pkt, Addr daddr) break; case TimerCounterReg: DPRINTF(Timer, "Event schedule for timer %d, clock=%d, prescale=%d\n", - timerZeroEvent.when(), clock, timerControl.prescalar); + timerZeroEvent.when(), parent->clockPeriod(), + timerControl.prescalar); time = timerZeroEvent.when() - curTick(); - time = time / clock / power(16, timerControl.prescalar); + time = time / parent->clockPeriod() / + power(16, timerControl.prescalar); DPRINTF(Timer, "-- returning counter at %d\n", time); pkt->set(time); break; @@ -120,10 +121,13 @@ CpuLocalTimer::Timer::read(PacketPtr pkt, Addr daddr) pkt->set(watchdogLoadValue); break; case WatchdogCounterReg: - DPRINTF(Timer, "Event schedule for watchdog %d, clock=%d, prescale=%d\n", - watchdogZeroEvent.when(), clock, watchdogControl.prescalar); + DPRINTF(Timer, + "Event schedule for watchdog %d, clock=%d, prescale=%d\n", + watchdogZeroEvent.when(), parent->clockPeriod(), + watchdogControl.prescalar); time = watchdogZeroEvent.when() - curTick(); - time = time / clock / power(16, watchdogControl.prescalar); + time = time / parent->clockPeriod() / + power(16, watchdogControl.prescalar); DPRINTF(Timer, "-- returning counter at %d\n", time); pkt->set(time); break; @@ -249,7 +253,7 @@ CpuLocalTimer::Timer::restartTimerCounter(uint32_t val) if (!timerControl.enable) return; - Tick time = clock * power(16, timerControl.prescalar); + Tick time = parent->clockPeriod() * power(16, timerControl.prescalar); time *= val; if (timerZeroEvent.scheduled()) { @@ -267,7 +271,7 @@ CpuLocalTimer::Timer::restartWatchdogCounter(uint32_t val) if (!watchdogControl.enable) return; - Tick time = clock * power(16, watchdogControl.prescalar); + Tick time = parent->clockPeriod() * power(16, watchdogControl.prescalar); time *= val; if (watchdogZeroEvent.scheduled()) { diff --git a/src/dev/arm/timer_cpulocal.hh b/src/dev/arm/timer_cpulocal.hh index 086dc1c63..f53f5bc25 100644 --- a/src/dev/arm/timer_cpulocal.hh +++ b/src/dev/arm/timer_cpulocal.hh @@ -103,9 +103,6 @@ class CpuLocalTimer : public BasicPioDevice /** Cpu this timer is attached to */ uint32_t cpuNum; - /** Number of ticks in a clock input */ - Tick clock; - /** Control register as specified above */ TimerCtrl timerControl; WatchdogCtrl watchdogControl; diff --git a/src/mem/bus.cc b/src/mem/bus.cc index a880eca8f..4d9cdbe88 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -132,37 +132,33 @@ BaseBus::getSlavePort(const std::string &if_name, PortID idx) Tick BaseBus::calcPacketTiming(PacketPtr pkt) { - // determine the current time rounded to the closest following + // determine the header time rounded to the closest following // clock edge - Tick now = nextCycle(); - - Tick headerTime = now + headerCycles * clock; + Tick headerTime = clockEdge(headerCycles); // The packet will be sent. Figure out how long it occupies the bus, and // how much of that time is for the first "word", aka bus width. - int numCycles = 0; + Cycles numCycles(0); if (pkt->hasData()) { // If a packet has data, it needs ceil(size/width) cycles to send it - int dataSize = pkt->getSize(); - numCycles += dataSize/width; - if (dataSize % width) - numCycles++; + unsigned dataSize = pkt->getSize(); + numCycles = Cycles(divCeil(dataSize, width)); } - // The first word will be delivered after the current tick, the delivery - // of the address if any, and one bus cycle to deliver the data - pkt->firstWordTime = headerTime + clock; + // The first word will be delivered on the cycle after the header. + pkt->firstWordTime = headerTime + clockPeriod(); - pkt->finishTime = headerTime + numCycles * clock; + // Note that currently finishTime can be smaller than + // firstWordTime if the packet has no data + pkt->finishTime = headerTime + numCycles * clockPeriod(); return headerTime; } template -BaseBus::Layer::Layer(BaseBus& _bus, const std::string& _name, - Tick _clock) : +BaseBus::Layer::Layer(BaseBus& _bus, const std::string& _name) : Drainable(), - bus(_bus), _name(_name), state(IDLE), clock(_clock), drainManager(NULL), + bus(_bus), _name(_name), state(IDLE), drainManager(NULL), releaseEvent(this) { } @@ -306,11 +302,8 @@ BaseBus::Layer::retryWaiting() // snoop responses state = BUSY; - // determine the current time rounded to the closest following - // clock edge - Tick now = bus.nextCycle(); - - occupyLayer(now + clock); + // occupy the bus layer until the next cycle ends + occupyLayer(bus.clockEdge(Cycles(1))); } } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 59dabbfe4..015bb51a0 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -105,9 +105,8 @@ class BaseBus : public MemObject * * @param _bus the bus this layer belongs to * @param _name the layer's name - * @param _clock clock period in ticks */ - Layer(BaseBus& _bus, const std::string& _name, Tick _clock); + Layer(BaseBus& _bus, const std::string& _name); /** * Drain according to the normal semantics, so that the bus @@ -203,9 +202,6 @@ class BaseBus : public MemObject /** track the state of the bus layer */ State state; - /** the clock speed for the bus layer */ - Tick clock; - /** manager to signal when drained */ DrainManager *drainManager; diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index d2c9f900e..a7e6a6186 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012 ARM Limited + * Copyright (c) 2010-2013 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -898,7 +898,7 @@ Cache::handleResponse(PacketPtr pkt) // responseLatency is the latency of the return path // from lower level caches/memory to an upper level cache or // the core. - completion_time = responseLatency * clock + + completion_time = responseLatency * clockPeriod() + (transfer_offset ? pkt->finishTime : pkt->firstWordTime); assert(!target->pkt->req->isUncacheable()); @@ -914,13 +914,15 @@ Cache::handleResponse(PacketPtr pkt) // responseLatency is the latency of the return path // from lower level caches/memory to an upper level cache or // the core. - completion_time = responseLatency * clock + pkt->finishTime; + completion_time = responseLatency * clockPeriod() + + pkt->finishTime; target->pkt->req->setExtraData(0); } else { // not a cache fill, just forwarding response // responseLatency is the latency of the return path // from lower level cahces/memory to the core. - completion_time = responseLatency * clock + pkt->finishTime; + completion_time = responseLatency * clockPeriod() + + pkt->finishTime; if (pkt->isRead() && !is_error) { target->pkt->setData(pkt->getPtr()); } diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index be05a464f..ddf1c1b31 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -241,7 +241,7 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time) prefetch->req->setThreadContext(pkt->req->contextId(), pkt->req->threadId()); - prefetch->time = time + clock * *delayIter; + prefetch->time = time + clockPeriod() * *delayIter; // We just remove the head if we are full if (pf.size() == size) { diff --git a/src/mem/coherent_bus.cc b/src/mem/coherent_bus.cc index f74ca48e9..409f69229 100644 --- a/src/mem/coherent_bus.cc +++ b/src/mem/coherent_bus.cc @@ -55,9 +55,9 @@ #include "sim/system.hh" CoherentBus::CoherentBus(const CoherentBusParams *p) - : BaseBus(p), reqLayer(*this, ".reqLayer", p->clock), - respLayer(*this, ".respLayer", p->clock), - snoopRespLayer(*this, ".snoopRespLayer", p->clock), + : BaseBus(p), reqLayer(*this, ".reqLayer"), + respLayer(*this, ".respLayer"), + snoopRespLayer(*this, ".snoopRespLayer"), system(p->system) { // create the ports based on the size of the master and slave diff --git a/src/mem/coherent_bus.hh b/src/mem/coherent_bus.hh index 05c45f69a..865bfe857 100644 --- a/src/mem/coherent_bus.hh +++ b/src/mem/coherent_bus.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall diff --git a/src/mem/noncoherent_bus.cc b/src/mem/noncoherent_bus.cc index f14f6e3d6..ae5344425 100644 --- a/src/mem/noncoherent_bus.cc +++ b/src/mem/noncoherent_bus.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -55,8 +55,8 @@ #include "mem/noncoherent_bus.hh" NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p) - : BaseBus(p), reqLayer(*this, ".reqLayer", p->clock), - respLayer(*this, ".respLayer", p->clock) + : BaseBus(p), reqLayer(*this, ".reqLayer"), + respLayer(*this, ".respLayer") { // create the ports based on the size of the master and slave // vector ports, and the presence of the default port, the ports diff --git a/src/mem/noncoherent_bus.hh b/src/mem/noncoherent_bus.hh index a42c26b2e..38b69a180 100644 --- a/src/mem/noncoherent_bus.hh +++ b/src/mem/noncoherent_bus.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall diff --git a/src/mem/ruby/system/RubyMemoryControl.cc b/src/mem/ruby/system/RubyMemoryControl.cc index 6212f049c..78fe69060 100644 --- a/src/mem/ruby/system/RubyMemoryControl.cc +++ b/src/mem/ruby/system/RubyMemoryControl.cc @@ -557,7 +557,7 @@ RubyMemoryControl::issueRequest(int bank) bank, m_event.scheduled() ? 'Y':'N'); if (req.m_msgptr) { // don't enqueue L3 writebacks - enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay); + enqueueToDirectory(req, Cycles(m_mem_ctl_latency + m_mem_fixed_delay)); } m_oldRequest[bank] = 0; markTfaw(rank); @@ -702,7 +702,7 @@ RubyMemoryControl::wakeup() m_idleCount--; if (m_idleCount > 0) { assert(!m_event.scheduled()); - schedule(m_event, curTick() + clock); + schedule(m_event, clockEdge(Cycles(1))); } } diff --git a/src/sim/clocked_object.hh b/src/sim/clocked_object.hh index b0aaa1721..e04e9338d 100644 --- a/src/sim/clocked_object.hh +++ b/src/sim/clocked_object.hh @@ -103,11 +103,11 @@ class ClockedObject : public SimObject tick += elapsedCycles * clock; } - protected: - // Clock period in ticks Tick clock; + protected: + /** * Create a clocked object and set the clock based on the * parameters. -- 2.30.2