diff -r da2fa2718585 -r 93f1c90b3226 src/arch/arm/table_walker.cc --- a/src/arch/arm/table_walker.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/arch/arm/table_walker.cc Thu Jul 26 13:22:44 2012 +0100 @@ -740,7 +740,7 @@ TableWalker::nextWalk(ThreadContext *tc) { if (pendingQueue.size()) - schedule(doProcessEvent, tc->getCpuPtr()->nextCycle(curTick()+1)); + schedule(doProcessEvent, tc->getCpuPtr()->clockEdge(1)); } diff -r da2fa2718585 -r 93f1c90b3226 src/arch/x86/mmapped_ipr.hh --- a/src/arch/x86/mmapped_ipr.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/arch/x86/mmapped_ipr.hh Thu Jul 26 13:22:44 2012 +0100 @@ -62,7 +62,7 @@ // Make sure we don't trot off the end of data. assert(offset + pkt->getSize() <= sizeof(MiscReg)); pkt->setData(((uint8_t *)&data) + offset); - return xc->getCpuPtr()->ticks(1); + return 1; } inline Tick @@ -76,7 +76,7 @@ assert(offset + pkt->getSize() <= sizeof(MiscReg)); pkt->writeData(((uint8_t *)&data) + offset); xc->setMiscReg(index, gtoh(data)); - return xc->getCpuPtr()->ticks(1); + return 1; } } diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/inorder/cpu.hh --- a/src/cpu/inorder/cpu.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/inorder/cpu.hh Thu Jul 26 13:22:44 2012 +0100 @@ -198,7 +198,7 @@ void scheduleTickEvent(int delay) { assert(!tickEvent.scheduled() || tickEvent.squashed()); - reschedule(&tickEvent, nextCycle(curTick() + ticks(delay)), true); + reschedule(&tickEvent, clockEdge(delay), true); } /** Unschedule tick event, regardless of its current state. */ diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/inorder/cpu.cc --- a/src/cpu/inorder/cpu.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/inorder/cpu.cc Thu Jul 26 13:22:44 2012 +0100 @@ -210,7 +210,7 @@ InOrderCPU::CPUEvent::scheduleEvent(int delay) { assert(!scheduled() || squashed()); - cpu->reschedule(this, cpu->nextCycle(curTick() + cpu->ticks(delay)), true); + cpu->reschedule(this, cpu->clockEdge(delay), true); } void @@ -399,7 +399,7 @@ frontEndSked = createFrontEndSked(); faultSked = createFaultSked(); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); lockAddr = 0; lockFlag = false; @@ -759,17 +759,17 @@ if (!tickEvent.scheduled()) { if (_status == SwitchedOut) { // increment stat - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); } else if (!activityRec.active()) { DPRINTF(InOrderCPU, "sleeping CPU.\n"); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); timesIdled++; } else { //Tick next_tick = curTick() + cycles(1); //tickEvent.schedule(next_tick); - schedule(&tickEvent, nextCycle(curTick() + 1)); + schedule(&tickEvent, clockEdge(1)); DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", - nextCycle(curTick() + 1)); + clockEdge(1)); } } @@ -957,7 +957,7 @@ CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, inst, event_pri); - Tick sked_tick = nextCycle(curTick() + ticks(delay)); + Tick sked_tick = clockEdge(delay); if (delay >= 0) { DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i, [tid:%i].\n", eventNames[c_event], curTick() + delay, tid); @@ -1694,7 +1694,9 @@ DPRINTF(Activity, "Waking up CPU\n"); - Tick extra_cycles = tickToCycles((curTick() - 1) - lastRunningCycle); + Tick extra_cycles = curCycle() - lastRunningCycle; + if (extra_cycles != 0) + --extra_cycles; idleCycles += extra_cycles; for (int stage_num = 0; stage_num < NumStages; stage_num++) { @@ -1703,7 +1705,7 @@ numCycles += extra_cycles; - schedule(&tickEvent, nextCycle(curTick())); + schedule(&tickEvent, nextCycle()); } // Lots of copied full system code...place into BaseCPU class? diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/inorder/resource_pool.cc --- a/src/cpu/inorder/resource_pool.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/inorder/resource_pool.cc Thu Jul 26 13:22:44 2012 +0100 @@ -238,7 +238,7 @@ { assert(delay >= 0); - Tick when = cpu->nextCycle(curTick() + cpu->ticks(delay)); + Tick when = cpu->clockEdge(delay); switch ((int)e_type) { @@ -460,7 +460,7 @@ { InOrderCPU *cpu = resPool->cpu; assert(!scheduled() || squashed()); - cpu->reschedule(this, cpu->nextCycle(curTick() + cpu->ticks(delay)), true); + cpu->reschedule(this, cpu->clockEdge(delay), true); } /** Unschedule resource event, regardless of its current state. */ diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/o3/cpu.hh --- a/src/cpu/o3/cpu.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/o3/cpu.hh Thu Jul 26 13:22:44 2012 +0100 @@ -211,9 +211,9 @@ void scheduleTickEvent(int delay) { if (tickEvent.squashed()) - reschedule(tickEvent, nextCycle(curTick() + ticks(delay))); + reschedule(tickEvent, clockEdge(delay)); else if (!tickEvent.scheduled()) - schedule(tickEvent, nextCycle(curTick() + ticks(delay))); + schedule(tickEvent, clockEdge(delay)); } /** Unschedule tick event, regardless of its current state. */ @@ -253,9 +253,9 @@ // Schedule thread to activate, regardless of its current state. if (activateThreadEvent[tid].squashed()) reschedule(activateThreadEvent[tid], - nextCycle(curTick() + ticks(delay))); + clockEdge(delay)); else if (!activateThreadEvent[tid].scheduled()) { - Tick when = nextCycle(curTick() + ticks(delay)); + Tick when = clockEdge(delay); // Check if the deallocateEvent is also scheduled, and make // sure they do not happen at same time causing a sleep that @@ -316,10 +316,10 @@ // Schedule thread to activate, regardless of its current state. if (deallocateContextEvent[tid].squashed()) reschedule(deallocateContextEvent[tid], - nextCycle(curTick() + ticks(delay))); + clockEdge(delay)); else if (!deallocateContextEvent[tid].scheduled()) schedule(deallocateContextEvent[tid], - nextCycle(curTick() + ticks(delay))); + clockEdge(delay)); } /** Unschedule thread deallocation in CPU */ diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/o3/cpu.cc Thu Jul 26 13:22:44 2012 +0100 @@ -386,7 +386,7 @@ // Setup the ROB for whichever stages need it. commit.setROB(&rob); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); lastActivatedCycle = 0; #if 0 @@ -623,13 +623,13 @@ getState() == SimObject::Drained) { DPRINTF(O3CPU, "Switched out!\n"); // increment stat - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); } else if (!activityRec.active() || _status == Idle) { DPRINTF(O3CPU, "Idle!\n"); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); timesIdled++; } else { - schedule(tickEvent, nextCycle(curTick() + ticks(1))); + schedule(tickEvent, clockEdge(1)); DPRINTF(O3CPU, "Scheduling next tick!\n"); } } @@ -762,7 +762,10 @@ activityRec.activity(); fetch.wakeFromQuiesce(); - quiesceCycles += tickToCycles((curTick() - 1) - lastRunningCycle); + Tick cycles = curCycle() - lastRunningCycle; + if (cycles != 0) + --cycles; + quiesceCycles += cycles; lastActivatedCycle = curTick(); @@ -801,7 +804,7 @@ unscheduleTickEvent(); DPRINTF(Quiesce, "Suspending Context\n"); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); _status = Idle; } @@ -1269,7 +1272,7 @@ if (!tickEvent.scheduled()) schedule(tickEvent, nextCycle()); - lastRunningCycle = curTick(); + lastRunningCycle = curCycle(); } template @@ -1663,8 +1666,11 @@ DPRINTF(Activity, "Waking up CPU\n"); - idleCycles += tickToCycles((curTick() - 1) - lastRunningCycle); - numCycles += tickToCycles((curTick() - 1) - lastRunningCycle); + Tick cycles = curCycle() - lastRunningCycle; + if (cycles != 0) + --cycles; + idleCycles += cycles; + numCycles += cycles; schedule(tickEvent, nextCycle()); } diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/o3/fetch_impl.hh --- a/src/cpu/o3/fetch_impl.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/o3/fetch_impl.hh Thu Jul 26 13:22:44 2012 +0100 @@ -645,7 +645,7 @@ assert(!finishTranslationEvent.scheduled()); finishTranslationEvent.setFault(fault); finishTranslationEvent.setReq(mem_req); - cpu->schedule(finishTranslationEvent, cpu->nextCycle(curTick() + cpu->ticks(1))); + cpu->schedule(finishTranslationEvent, cpu->clockEdge(1)); return; } DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n", diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/o3/lsq_unit.hh --- a/src/cpu/o3/lsq_unit.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/o3/lsq_unit.hh Thu Jul 26 13:22:44 2012 +0100 @@ -624,7 +624,7 @@ delete snd_data_pkt; } WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); - cpu->schedule(wb, curTick() + delay); + cpu->schedule(wb, cpu->clockEdge(delay)); return NoFault; } diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/simple/atomic.cc --- a/src/cpu/simple/atomic.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/simple/atomic.cc Thu Jul 26 13:22:44 2012 +0100 @@ -207,10 +207,10 @@ assert(!tickEvent.scheduled()); notIdleFraction++; - numCycles += tickToCycles(thread->lastActivate - thread->lastSuspend); + numCycles += tickToCycle(thread->lastActivate - thread->lastSuspend); //Make sure ticks are still on multiples of cycles - schedule(tickEvent, nextCycle(curTick() + ticks(delay))); + schedule(tickEvent, clockEdge(delay)); _status = Running; } diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/simple/timing.hh --- a/src/cpu/simple/timing.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/simple/timing.hh Thu Jul 26 13:22:44 2012 +0100 @@ -244,7 +244,7 @@ PacketPtr ifetch_pkt; PacketPtr dcache_pkt; - Tick previousTick; + Tick previousCycle; public: diff -r da2fa2718585 -r 93f1c90b3226 src/cpu/simple/timing.cc --- a/src/cpu/simple/timing.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/cpu/simple/timing.cc Thu Jul 26 13:22:44 2012 +0100 @@ -87,13 +87,10 @@ TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p) : BaseSimpleCPU(p, icacheHandler, dcacheHandler), fetchTranslation(this), icacheHandler(this), dcacheHandler(this), - fetchEvent(this) + ifetch_pkt(NULL), dcache_pkt(NULL), previousCycle(0), fetchEvent(this) { _status = Idle; - ifetch_pkt = dcache_pkt = NULL; - drainEvent = NULL; - previousTick = 0; changeState(SimObject::Running); system->totalNumInsts = 0; } @@ -155,7 +152,7 @@ { assert(_status == Running || _status == Idle); _status = SwitchedOut; - numCycles += tickToCycles(curTick() - previousTick); + numCycles += curCycle() - previousCycle; // If we've been scheduled to resume but are then told to switch out, // we'll need to cancel it. @@ -183,7 +180,7 @@ _status = Idle; } assert(threadContexts.size() == 1); - previousTick = curTick(); + previousCycle = curCycle(); } @@ -201,7 +198,7 @@ _status = Running; // kick things off by initiating the fetch of the next instruction - schedule(fetchEvent, nextCycle(curTick() + ticks(delay))); + schedule(fetchEvent, clockEdge(delay)); } @@ -230,9 +227,8 @@ { RequestPtr req = pkt->req; if (req->isMmappedIpr()) { - Tick delay; - delay = TheISA::handleIprRead(thread->getTC(), pkt); - new IprEvent(pkt, this, nextCycle(curTick() + delay)); + Tick delay = TheISA::handleIprRead(thread->getTC(), pkt); + new IprEvent(pkt, this, clockEdge(delay)); _status = DcacheWaitResponse; dcache_pkt = NULL; } else if (!dcachePort->sendTimingReq(pkt)) { @@ -321,8 +317,8 @@ { // fault may be NoFault in cases where a fault is suppressed, // for instance prefetches. - numCycles += tickToCycles(curTick() - previousTick); - previousTick = curTick(); + numCycles += curCycle() - previousCycle; + previousCycle = curCycle(); if (traceData) { // Since there was a fault, we shouldn't trace this instruction. @@ -445,9 +441,8 @@ { RequestPtr req = dcache_pkt->req; if (req->isMmappedIpr()) { - Tick delay; - delay = TheISA::handleIprWrite(thread->getTC(), dcache_pkt); - new IprEvent(dcache_pkt, this, nextCycle(curTick() + delay)); + Tick delay = TheISA::handleIprWrite(thread->getTC(), dcache_pkt); + new IprEvent(dcache_pkt, this, clockEdge(delay)); _status = DcacheWaitResponse; dcache_pkt = NULL; } else if (!dcachePort->sendTimingReq(dcache_pkt)) { @@ -566,8 +561,8 @@ _status = IcacheWaitResponse; completeIfetch(NULL); - numCycles += tickToCycles(curTick() - previousTick); - previousTick = curTick(); + numCycles += curCycle() - previousCycle; + previousCycle = curCycle(); } } @@ -599,8 +594,8 @@ advanceInst(fault); } - numCycles += tickToCycles(curTick() - previousTick); - previousTick = curTick(); + numCycles += curCycle() - previousCycle; + previousCycle = curCycle(); } @@ -646,8 +641,8 @@ _status = Running; - numCycles += tickToCycles(curTick() - previousTick); - previousTick = curTick(); + numCycles += curCycle() - previousCycle; + previousCycle = curCycle(); if (getState() == SimObject::Draining) { if (pkt) { @@ -721,7 +716,7 @@ if (!pkt->wasNacked()) { DPRINTF(SimpleCPU, "Received timing response %#x\n", pkt->getAddr()); // delay processing of returned data until next CPU clock edge - Tick next_tick = cpu->nextCycle(curTick()); + Tick next_tick = cpu->nextCycle(); if (next_tick == curTick()) cpu->completeIfetch(pkt); @@ -764,8 +759,8 @@ assert(_status == DcacheWaitResponse || _status == DTBWaitResponse || pkt->req->getFlags().isSet(Request::NO_ACCESS)); - numCycles += tickToCycles(curTick() - previousTick); - previousTick = curTick(); + numCycles += curCycle() - previousCycle; + previousCycle = curCycle(); if (pkt->senderState) { SplitFragmentSenderState * send_state = @@ -840,7 +835,7 @@ { if (!pkt->wasNacked()) { // delay processing of returned data until next CPU clock edge - Tick next_tick = cpu->nextCycle(curTick()); + Tick next_tick = cpu->nextCycle(); if (next_tick == curTick()) { cpu->completeDataAccess(pkt); diff -r da2fa2718585 -r 93f1c90b3226 src/dev/arm/pl111.cc --- a/src/dev/arm/pl111.cc Thu Jul 26 12:56:49 2012 +0100 +++ b/src/dev/arm/pl111.cc Thu Jul 26 13:22:44 2012 +0100 @@ -440,7 +440,7 @@ schedule(intEvent, nextCycle()); curAddr = 0; - startTime = curTick(); + startTime = curCycle(); maxAddr = static_cast(length * bytesPerPixel); @@ -475,12 +475,12 @@ void Pl111::dmaDone() { - Tick maxFrameTime = lcdTiming2.cpl * height * clock; + Tick maxFrameTime = lcdTiming2.cpl * height; --dmaPendingNum; if (maxAddr == curAddr && !dmaPendingNum) { - if ((curTick() - startTime) > maxFrameTime) { + if ((curCycle() - startTime) > maxFrameTime) { warn("CLCD controller buffer underrun, took %d cycles when should" " have taken %d\n", curTick() - startTime, maxFrameTime); lcdRis.underflow = 1; @@ -498,11 +498,13 @@ pic->seekp(0); bmp->write(pic); - DPRINTF(PL111, "-- schedule next dma read event at %d tick \n", - maxFrameTime + curTick()); - + // schedule the next read based on when the last frame started + // and the desired fps (i.e. maxFrameTime), we turn the + // argument into a relative number of cycles in the future by + // subtracting curCycle() if (lcdControl.lcden) - schedule(readEvent, nextCycle(startTime + maxFrameTime)); + schedule(readEvent, clockEdge(startTime + maxFrameTime - + curCycle())); } if (dmaPendingNum > (maxOutstandingDma - waterMark)) diff -r da2fa2718585 -r 93f1c90b3226 src/sim/clocked_object.hh --- a/src/sim/clocked_object.hh Thu Jul 26 12:56:49 2012 +0100 +++ b/src/sim/clocked_object.hh Thu Jul 26 13:22:44 2012 +0100 @@ -58,6 +58,12 @@ private: + // The cycle as seen the last time we updated + mutable Tick cycle; + + // The tick as seen the last time we updated + mutable Tick tick; + /** * Prevent inadvertent use of the copy constructor and assignment * operator by making them private. @@ -65,6 +71,28 @@ ClockedObject(ClockedObject&); ClockedObject& operator=(ClockedObject&); + /** + * Align cycle and tick to the next clock edge if not already done. + */ + void update() const + { + if (tick == curTick()) + return; + + // see if we did something the last cycle + tick += clock; + + if (tick == curTick()) { + // if so, increment the cycle count. + cycle += 1; + return; + } + + // if not, we must manually recalculate everything + cycle = divCeil(curTick(), clock); + tick = cycle * clock; + } + protected: // Clock period in ticks @@ -74,7 +102,8 @@ * Create a clocked object and set the clock based on the * parameters. */ - ClockedObject(const ClockedObjectParams* p) : SimObject(p), clock(p->clock) + ClockedObject(const ClockedObjectParams* p) : + SimObject(p), cycle(0), tick(0), clock(p->clock) { } /** @@ -85,33 +114,51 @@ public: /** + * Determine the tick when a cycle begins, by default the current + * one, but the argument also enables the caller to determine a + * future cycle. + * + * @param cycles The number of cycles into the future + * + * @return The tick when the clock edge occurs + */ + inline Tick clockEdge(int cycles = 0) const + { + // align tick to the next clock edge + update(); + + // figure out when this future cycle is + return tick + ticks(cycles); + } + + /** + * Determine the current cycle, corresponding to a tick aligned to + * a clock edge. + * + * @return The current cycle + */ + inline Tick curCycle() const + { + // align cycle to the next clock edge. + update(); + + return cycle; + } + + /** * 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. + * next cycle begins, in other words, return the next clock edge. * * @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; } + { return clockEdge(); } inline Tick frequency() const { return SimClock::Frequency / clock; } - inline Tick ticks(int numCycles) const { return clock * numCycles; } + inline Tick ticks(int cycles) const { return clock * cycles; } - inline Tick curCycle() const { return curTick() / clock; } - - inline Tick tickToCycles(Tick val) const { return val / clock; } + inline Tick tickToCycle(Tick tick) const { return tick / clock; } };