Clean up clock phase drift code a bit.
authorKevin Lim <ktlim@umich.edu>
Mon, 6 Nov 2006 18:27:45 +0000 (13:27 -0500)
committerKevin Lim <ktlim@umich.edu>
Mon, 6 Nov 2006 18:27:45 +0000 (13:27 -0500)
src/cpu/base.cc:
    Move clock phase drift code to the base CPU so that any CPU model can use it.
src/cpu/base.hh:
    Added two functions to help get the next cycle the CPU should be scheduled.
src/cpu/simple/atomic.cc:
src/cpu/simple/timing.cc:
    Use the function now in BaseCPU.

--HG--
extra : convert_revision : 444494b66ffc85fc473c23f57683c5f9458ad80c

src/cpu/base.cc
src/cpu/base.hh
src/cpu/simple/atomic.cc
src/cpu/simple/timing.cc

index ea4b03bf286a44f945c3279451e6c492345b132e..55ceea8fb05d3e916c7fa45df775f181dc7c337f 100644 (file)
@@ -259,6 +259,26 @@ BaseCPU::regStats()
 #endif
 }
 
+Tick
+BaseCPU::nextCycle()
+{
+    Tick next_tick = curTick + clock - 1;
+    next_tick -= (next_tick % clock);
+    return next_tick;
+}
+
+Tick
+BaseCPU::nextCycle(Tick begin_tick)
+{
+    Tick next_tick = begin_tick;
+
+    while (next_tick < curTick)
+        next_tick += clock;
+
+    next_tick -= (next_tick % clock);
+    assert(next_tick >= curTick);
+    return next_tick;
+}
 
 void
 BaseCPU::registerThreadContexts()
index 75e0d86af4e910e221eae6a784475ad7016b80e6..df665ed2327fa9877de22c8b945656a0e0361389 100644 (file)
@@ -73,6 +73,20 @@ class BaseCPU : public MemObject
     inline Tick cycles(int numCycles) const { return clock * numCycles; }
     inline Tick curCycle() const { return curTick / clock; }
 
+    /** 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);
+
 #if FULL_SYSTEM
   protected:
     uint64_t interrupts[TheISA::NumInterruptLevels];
index 72249be41678684fdcdd585a5437be2f8feaa5d7..4f68cfd6fdfc62ffea9c64db7fb932f962a7960d 100644 (file)
@@ -180,9 +180,7 @@ AtomicSimpleCPU::resume()
         changeState(SimObject::Running);
         if (thread->status() == ThreadContext::Active) {
             if (!tickEvent.scheduled()) {
-                Tick nextTick = curTick + cycles(1) - 1;
-                nextTick -= (nextTick % (cycles(1)));
-                tickEvent.schedule(nextTick);
+                tickEvent.schedule(nextCycle());
             }
         }
     }
@@ -211,9 +209,7 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
         ThreadContext *tc = threadContexts[i];
         if (tc->status() == ThreadContext::Active && _status != Running) {
             _status = Running;
-            Tick nextTick = curTick + cycles(1) - 1;
-            nextTick -= (nextTick % (cycles(1)));
-            tickEvent.schedule(nextTick);
+            tickEvent.schedule(nextCycle());
             break;
         }
     }
@@ -231,9 +227,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
 
     notIdleFraction++;
     //Make sure ticks are still on multiples of cycles
-    Tick nextTick = curTick + cycles(delay + 1) - 1;
-    nextTick -= (nextTick % (cycles(1)));
-    tickEvent.schedule(nextTick);
+    tickEvent.schedule(nextCycle(curTick + cycles(delay)));
     _status = Running;
 }
 
index 4d57bf6d571219957c48a513b3ec0a098740bedc..abf31609565c097e6022884529509b2e01d42386 100644 (file)
@@ -532,14 +532,13 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
 {
     if (pkt->isResponse()) {
         // delay processing of returned data until next CPU clock edge
-        Tick time = pkt->req->getTime();
-        while (time < curTick)
-            time += lat;
+        Tick mem_time = pkt->req->getTime();
+        Tick next_tick = cpu->nextCycle(mem_time);
 
-        if (time == curTick)
+        if (next_tick == curTick)
             cpu->completeIfetch(pkt);
         else
-            tickEvent.schedule(pkt, time);
+            tickEvent.schedule(pkt, next_tick);
 
         return true;
     }
@@ -610,14 +609,13 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
 {
     if (pkt->isResponse()) {
         // delay processing of returned data until next CPU clock edge
-        Tick time = pkt->req->getTime();
-        while (time < curTick)
-            time += lat;
+        Tick mem_time = pkt->req->getTime();
+        Tick next_tick = cpu->nextCycle(mem_time);
 
-        if (time == curTick)
+        if (next_tick == curTick)
             cpu->completeDataAccess(pkt);
         else
-            tickEvent.schedule(pkt, time);
+            tickEvent.schedule(pkt, next_tick);
 
         return true;
     }