2c2
< * Copyright (c) 2010-2012 ARM Limited
---
> * Copyright (c) 2010-2013 ARM Limited
52,54c52,55
< port(name() + ".port", *this), lat(p->latency),
< lat_var(p->latency_var), bandwidth(p->bandwidth),
< isBusy(false), retryReq(false), releaseEvent(this)
---
> port(name() + ".port", *this), latency(p->latency),
> latency_var(p->latency_var), bandwidth(p->bandwidth), isBusy(false),
> retryReq(false), retryResp(false),
> releaseEvent(this), dequeueEvent(this), drainManager(NULL)
69c70
< SimpleMemory::calculateLatency(PacketPtr pkt)
---
> SimpleMemory::recvAtomic(PacketPtr pkt)
71,83d71
< if (pkt->memInhibitAsserted()) {
< return 0;
< } else {
< Tick latency = lat;
< if (lat_var != 0)
< latency += random_mt.random<Tick>(0, lat_var);
< return latency;
< }
< }
<
< Tick
< SimpleMemory::doAtomicAccess(PacketPtr pkt)
< {
85c73
< return calculateLatency(pkt);
---
> return pkt->memInhibitAsserted() ? 0 : getLatency();
89c77
< SimpleMemory::doFunctionalAccess(PacketPtr pkt)
---
> SimpleMemory::recvFunctional(PacketPtr pkt)
90a79,80
> pkt->pushLabel(name());
>
91a82,87
>
> // potentially update the packets in our packet queue as well
> for (auto i = packetQueue.begin(); i != packetQueue.end(); ++i)
> pkt->checkFunctional(i->pkt);
>
> pkt->popLabel();
152c148
< Tick latency = doAtomicAccess(pkt);
---
> recvAtomic(pkt);
155c151
< // doAtomicAccess() should already have turned packet into
---
> // recvAtomic() should already have turned packet into
158c154,159
< port.schedTimingResp(pkt, curTick() + latency);
---
> // to keep things simple (and in order), we put the packet at
> // the end even if the latency suggests it should be sent
> // before the packet(s) before it
> packetQueue.push_back(DeferredPacket(pkt, curTick() + getLatency()));
> if (!dequeueEvent.scheduled())
> schedule(dequeueEvent, packetQueue.back().tick);
176a178,217
> void
> SimpleMemory::dequeue()
> {
> assert(!packetQueue.empty());
> DeferredPacket deferred_pkt = packetQueue.front();
>
> retryResp = !port.sendTimingResp(deferred_pkt.pkt);
>
> if (!retryResp) {
> packetQueue.pop_front();
>
> // if the queue is not empty, schedule the next dequeue event,
> // otherwise signal that we are drained if we were asked to do so
> if (!packetQueue.empty()) {
> // if there were packets that got in-between then we
> // already have an event scheduled, so use re-schedule
> reschedule(dequeueEvent,
> std::max(packetQueue.front().tick, curTick()), true);
> } else if (drainManager) {
> drainManager->signalDrainDone();
> drainManager = NULL;
> }
> }
> }
>
> Tick
> SimpleMemory::getLatency() const
> {
> return latency +
> (latency_var ? random_mt.random<Tick>(0, latency_var) : 0);
> }
>
> void
> SimpleMemory::recvRetry()
> {
> assert(retryResp);
>
> dequeue();
> }
>
190c231
< int count = port.drain(dm);
---
> int count = 0;
191a233,238
> // also track our internal queue
> if (!packetQueue.empty()) {
> count += 1;
> drainManager = dm;
> }
>
201,202c248
< : QueuedSlavePort(_name, &_memory, queueImpl),
< queueImpl(_memory, *this), memory(_memory)
---
> : SlavePort(_name, &_memory), memory(_memory)
216c262
< return memory.doAtomicAccess(pkt);
---
> return memory.recvAtomic(pkt);
222,231c268
< pkt->pushLabel(memory.name());
<
< if (!queue.checkFunctional(pkt)) {
< // Default implementation of SimpleTimingPort::recvFunctional()
< // calls recvAtomic() and throws away the latency; we can save a
< // little here by just not calculating the latency.
< memory.doFunctionalAccess(pkt);
< }
<
< pkt->popLabel();
---
> memory.recvFunctional(pkt);
239a277,282
> void
> SimpleMemory::MemoryPort::recvRetry()
> {
> memory.recvRetry();
> }
>