changeset f10eb34e3e38 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=f10eb34e3e38
description:
        sim: separate nextCycle() and clockEdge() in clockedObjects

        Previously, nextCycle() could return the *current* cycle if the current 
tick was
        already aligned with the clock edge. This behavior is not only 
confusing (not
        quite what the function name implies), but also caused problems in the
        drainResume() function. When exiting/re-entering the sim loop (e.g., to 
take
        checkpoints), the CPUs will drain and resume. Due to the previous 
behavior of
        nextCycle(), the CPU tick events were being rescheduled in the same 
ticks that
        were already processed before draining. This caused divergence from 
runs that
        did not exit/re-entered the sim loop. (Initially a cycle difference, 
but a
        significant impact later on.)

        This patch separates out the two behaviors (nextCycle() and 
clockEdge()),
        uses nextCycle() in drainResume, and uses clockEdge() everywhere else.
        Nothing (other than name) should change except for the drainResume 
timing.

diffstat:

 src/cpu/inorder/cpu.cc                   |  2 +-
 src/cpu/o3/cpu.cc                        |  2 +-
 src/cpu/simple/timing.cc                 |  8 ++++----
 src/dev/arm/hdlcd.cc                     |  8 ++++----
 src/dev/arm/pl111.cc                     |  6 +++---
 src/mem/bridge.cc                        |  4 ++--
 src/mem/bus.cc                           |  2 +-
 src/mem/ruby/system/RubyMemoryControl.cc |  2 +-
 src/sim/clocked_object.hh                |  7 ++++---
 9 files changed, 21 insertions(+), 20 deletions(-)

diffs (198 lines):

diff -r 5b6b315472e7 -r f10eb34e3e38 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Mon Apr 22 13:20:31 2013 -0400
+++ b/src/cpu/inorder/cpu.cc    Mon Apr 22 13:20:31 2013 -0400
@@ -1715,7 +1715,7 @@
 
     numCycles += extra_cycles;
 
-    schedule(&tickEvent, nextCycle());
+    schedule(&tickEvent, clockEdge());
 }
 
 // Lots of copied full system code...place into BaseCPU class?
diff -r 5b6b315472e7 -r f10eb34e3e38 src/cpu/o3/cpu.cc
--- a/src/cpu/o3/cpu.cc Mon Apr 22 13:20:31 2013 -0400
+++ b/src/cpu/o3/cpu.cc Mon Apr 22 13:20:31 2013 -0400
@@ -1720,7 +1720,7 @@
     idleCycles += cycles;
     numCycles += cycles;
 
-    schedule(tickEvent, nextCycle());
+    schedule(tickEvent, clockEdge());
 }
 
 template <class Impl>
diff -r 5b6b315472e7 -r f10eb34e3e38 src/cpu/simple/timing.cc
--- a/src/cpu/simple/timing.cc  Mon Apr 22 13:20:31 2013 -0400
+++ b/src/cpu/simple/timing.cc  Mon Apr 22 13:20:31 2013 -0400
@@ -120,7 +120,7 @@
         // succeed on the first attempt. We need to reschedule it if
         // the CPU is waiting for a microcode routine to complete.
         if (_status == BaseSimpleCPU::Running && !fetchEvent.scheduled())
-            schedule(fetchEvent, nextCycle());
+            schedule(fetchEvent, clockEdge());
 
         return 1;
     }
@@ -616,7 +616,7 @@
     if (fault != NoFault) {
         advancePC(fault);
         DPRINTF(SimpleCPU, "Fault occured, scheduling fetch event\n");
-        reschedule(fetchEvent, nextCycle(), true);
+        reschedule(fetchEvent, clockEdge(), true);
         _status = Faulting;
         return;
     }
@@ -715,7 +715,7 @@
 {
     DPRINTF(SimpleCPU, "Received timing response %#x\n", pkt->getAddr());
     // delay processing of returned data until next CPU clock edge
-    Tick next_tick = cpu->nextCycle();
+    Tick next_tick = cpu->clockEdge();
 
     if (next_tick == curTick())
         cpu->completeIfetch(pkt);
@@ -807,7 +807,7 @@
 TimingSimpleCPU::DcachePort::recvTimingResp(PacketPtr pkt)
 {
     // delay processing of returned data until next CPU clock edge
-    Tick next_tick = cpu->nextCycle();
+    Tick next_tick = cpu->clockEdge();
 
     if (next_tick == curTick()) {
         cpu->completeDataAccess(pkt);
diff -r 5b6b315472e7 -r f10eb34e3e38 src/dev/arm/hdlcd.cc
--- a/src/dev/arm/hdlcd.cc      Mon Apr 22 13:20:31 2013 -0400
+++ b/src/dev/arm/hdlcd.cc      Mon Apr 22 13:20:31 2013 -0400
@@ -282,7 +282,7 @@
             if (new_command.enable) {
                 doUpdateParams = true;
                 if (!frameUnderway) {
-                    schedule(startFrameEvent, nextCycle());
+                    schedule(startFrameEvent, clockEdge());
                 }
             }
         }
@@ -514,7 +514,7 @@
             frameUnderrun = true;
             int_rawstat.underrun = 1;
             if (!intEvent.scheduled())
-                schedule(intEvent, nextCycle());
+                schedule(intEvent, clockEdge());
         } else {
             // emulate the pixel read from the internal buffer
             pixelBufferSize -= bytesPerPixel() * count;
@@ -524,7 +524,7 @@
     // the DMA may have previously stalled due to the buffer being full;
     //   give it a kick; it knows not to fill if at end of frame, underrun, etc
     if (!fillPixelBufferEvent.scheduled())
-        schedule(fillPixelBufferEvent, nextCycle());
+        schedule(fillPixelBufferEvent, clockEdge());
 
     // schedule the next pixel read according to where it is in the frame
     pixelIndex += count;
@@ -597,7 +597,7 @@
     if ((dmaCurAddr < dmaMaxAddr) &&
         (bytesFreeInPixelBuffer() + targetTransSize < PIXEL_BUFFER_CAPACITY) &&
         !fillPixelBufferEvent.scheduled()) {
-        schedule(fillPixelBufferEvent, nextCycle());
+        schedule(fillPixelBufferEvent, clockEdge());
     }
 }
 
diff -r 5b6b315472e7 -r f10eb34e3e38 src/dev/arm/pl111.cc
--- a/src/dev/arm/pl111.cc      Mon Apr 22 13:20:31 2013 -0400
+++ b/src/dev/arm/pl111.cc      Mon Apr 22 13:20:31 2013 -0400
@@ -441,7 +441,7 @@
     // Updating base address, interrupt if we're supposed to
     lcdRis.baseaddr = 1;
     if (!intEvent.scheduled())
-        schedule(intEvent, nextCycle());
+        schedule(intEvent, clockEdge());
 
     curAddr = 0;
     startTime = curTick();
@@ -492,7 +492,7 @@
                  " have taken %d\n", curTick() - startTime, maxFrameTime);
             lcdRis.underflow = 1;
             if (!intEvent.scheduled())
-                schedule(intEvent, nextCycle());
+                schedule(intEvent, clockEdge());
         }
 
         assert(!readEvent.scheduled());
@@ -522,7 +522,7 @@
         return;
 
     if (!fillFifoEvent.scheduled())
-        schedule(fillFifoEvent, nextCycle());
+        schedule(fillFifoEvent, clockEdge());
 }
 
 void
diff -r 5b6b315472e7 -r f10eb34e3e38 src/mem/bridge.cc
--- a/src/mem/bridge.cc Mon Apr 22 13:20:31 2013 -0400
+++ b/src/mem/bridge.cc Mon Apr 22 13:20:31 2013 -0400
@@ -277,7 +277,7 @@
             req = transmitList.front();
             DPRINTF(Bridge, "Scheduling next send\n");
             bridge.schedule(sendEvent, std::max(req.tick,
-                                                bridge.nextCycle()));
+                                                bridge.clockEdge()));
         }
 
         // if we have stalled a request due to a full request queue,
@@ -318,7 +318,7 @@
             resp = transmitList.front();
             DPRINTF(Bridge, "Scheduling next send\n");
             bridge.schedule(sendEvent, std::max(resp.tick,
-                                                bridge.nextCycle()));
+                                                bridge.clockEdge()));
         }
 
         // if there is space in the request queue and we were stalling
diff -r 5b6b315472e7 -r f10eb34e3e38 src/mem/bus.cc
--- a/src/mem/bus.cc    Mon Apr 22 13:20:31 2013 -0400
+++ b/src/mem/bus.cc    Mon Apr 22 13:20:31 2013 -0400
@@ -135,7 +135,7 @@
     // the bus will be called at a time that is not necessarily
     // coinciding with its own clock, so start by determining how long
     // until the next clock edge (could be zero)
-    Tick offset = nextCycle() - curTick();
+    Tick offset = clockEdge() - curTick();
 
     // determine how many cycles are needed to send the data
     unsigned dataCycles = pkt->hasData() ? divCeil(pkt->getSize(), width) : 0;
diff -r 5b6b315472e7 -r f10eb34e3e38 src/mem/ruby/system/RubyMemoryControl.cc
--- a/src/mem/ruby/system/RubyMemoryControl.cc  Mon Apr 22 13:20:31 2013 -0400
+++ b/src/mem/ruby/system/RubyMemoryControl.cc  Mon Apr 22 13:20:31 2013 -0400
@@ -307,7 +307,7 @@
     m_input_queue.push_back(memRef);
 
     if (!m_event.scheduled()) {
-        schedule(m_event, nextCycle());
+        schedule(m_event, clockEdge());
     }
 }
 
diff -r 5b6b315472e7 -r f10eb34e3e38 src/sim/clocked_object.hh
--- a/src/sim/clocked_object.hh Mon Apr 22 13:20:31 2013 -0400
+++ b/src/sim/clocked_object.hh Mon Apr 22 13:20:31 2013 -0400
@@ -172,13 +172,14 @@
     }
 
     /**
-     * Based on the clock of the object, determine the tick when the
-     * next cycle begins, in other words, return the next clock edge.
+     * Based on the clock of the object, determine the tick when the next
+     * cycle begins, in other words, return the next clock edge.
+     * (This can never be the current tick.)
      *
      * @return The tick when the next cycle starts
      */
     Tick nextCycle() const
-    { return clockEdge(); }
+    { return clockEdge(Cycles(1)); }
 
     inline uint64_t frequency() const { return SimClock::Frequency / clock; }
 
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to