sim: Make clock private and access using clockPeriod()
authorAndreas Hansson <andreas.hansson@arm.com>
Tue, 19 Feb 2013 10:56:06 +0000 (05:56 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Tue, 19 Feb 2013 10:56:06 +0000 (05:56 -0500)
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.

12 files changed:
src/dev/arm/timer_cpulocal.cc
src/dev/arm/timer_cpulocal.hh
src/mem/bus.cc
src/mem/bus.hh
src/mem/cache/cache_impl.hh
src/mem/cache/prefetch/base.cc
src/mem/coherent_bus.cc
src/mem/coherent_bus.hh
src/mem/noncoherent_bus.cc
src/mem/noncoherent_bus.hh
src/mem/ruby/system/RubyMemoryControl.cc
src/sim/clocked_object.hh

index 84bc12aa91aaf5fdf9f5f86096af496b966c560f..458df06749b9a447c9c622cb4093c829fa6e3c74 100644 (file)
@@ -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<uint32_t>(time);
         break;
@@ -120,10 +121,13 @@ CpuLocalTimer::Timer::read(PacketPtr pkt, Addr daddr)
         pkt->set<uint32_t>(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<uint32_t>(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()) {
index 086dc1c63a3596f5e1423cfcd6021d65ca6cf5a2..f53f5bc25910ac35007a1394ac3db9aa3c6d2dc1 100644 (file)
@@ -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;
index a880eca8f2318d46aea270b91d47b2b1b7240c29..4d9cdbe885ed2b120d72be10e8f56b09faed5310 100644 (file)
@@ -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 <typename PortClass>
-BaseBus::Layer<PortClass>::Layer(BaseBus& _bus, const std::string& _name,
-                                 Tick _clock) :
+BaseBus::Layer<PortClass>::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<PortClass>::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)));
     }
 }
 
index 59dabbfe418ace8e7bf32884c294d7835fe54d2f..015bb51a04003adc0061c91f3e945119587ee991 100644 (file)
@@ -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;
 
index d2c9f900ef99bc15a8220c4c2a19d44deca6a3ad..a7e6a6186b46fe4c6e79e954074e9233a278d630 100644 (file)
@@ -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<TagStore>::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<TagStore>::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<uint8_t>());
                 }
index be05a464f337ea2b71a8c29efb473b6f23a11cd2..ddf1c1b31348b8106455c05fb0c20e84419aea59 100644 (file)
@@ -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) {
index f74ca48e989795e3f9f588826bc088502493c676..409f69229375a792d3ffaf97805c997ecaf67e9e 100644 (file)
@@ -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
index 05c45f69a1f37bfbea8293c23ffbee4ddeb77a9b..865bfe8575763aebc572c39cf37a0db66a719927 100644 (file)
@@ -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
index f14f6e3d66d024a13eaf4cbaac12423a1e0203b0..ae5344425fe1cbf312a57640c6fa56f236698255 100644 (file)
@@ -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
index a42c26b2e989ca1082aca335f9d5fb0d636df39c..38b69a1808c57422aa8895037f774417c87e52b6 100644 (file)
@@ -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
index 6212f049ceee8e08e704c580edb8901eeee94f6b..78fe6906027357f417c9036c82c1936830bd33fa 100644 (file)
@@ -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)));
     }
 }
 
index b0aaa17210fab62cd165eebd62160f92907fe4d8..e04e9338d560c98c9431224e6c906932670ec43d 100644 (file)
@@ -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.