summaryrefslogtreecommitdiff
path: root/src/mem/simple_mem.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/simple_mem.hh')
-rw-r--r--src/mem/simple_mem.hh101
1 files changed, 83 insertions, 18 deletions
diff --git a/src/mem/simple_mem.hh b/src/mem/simple_mem.hh
index ab002f270..ba4b8bdf1 100644
--- a/src/mem/simple_mem.hh
+++ b/src/mem/simple_mem.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -49,15 +49,16 @@
#ifndef __SIMPLE_MEMORY_HH__
#define __SIMPLE_MEMORY_HH__
+#include <deque>
+
#include "mem/abstract_mem.hh"
-#include "mem/tport.hh"
+#include "mem/port.hh"
#include "params/SimpleMemory.hh"
/**
* The simple memory is a basic single-ported memory controller with
- * an configurable throughput and latency, potentially with a variance
- * added to the latter. It uses a QueueSlavePort to avoid dealing with
- * the flow control of sending responses.
+ * a configurable throughput and latency.
+ *
* @sa \ref gem5MemorySystem "gem5 Memory System"
*/
class SimpleMemory : public AbstractMemory
@@ -65,13 +66,27 @@ class SimpleMemory : public AbstractMemory
private:
- class MemoryPort : public QueuedSlavePort
+ /**
+ * A deferred packet stores a packet along with its scheduled
+ * transmission time
+ */
+ class DeferredPacket
+ {
+
+ public:
+
+ const Tick tick;
+ const PacketPtr pkt;
+
+ DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
+ { }
+ };
+
+ class MemoryPort : public SlavePort
{
private:
- /// Queue holding the response packets
- SlavePacketQueue queueImpl;
SimpleMemory& memory;
public:
@@ -86,16 +101,37 @@ class SimpleMemory : public AbstractMemory
bool recvTimingReq(PacketPtr pkt);
+ void recvRetry();
+
AddrRangeList getAddrRanges() const;
};
MemoryPort port;
- Tick lat;
- Tick lat_var;
+ /**
+ * Latency from that a request is accepted until the response is
+ * ready to be sent.
+ */
+ const Tick latency;
+
+ /**
+ * Fudge factor added to the latency.
+ */
+ const Tick latency_var;
+
+ /**
+ * Internal (unbounded) storage to mimic the delay caused by the
+ * actual memory access. Note that this is where the packet spends
+ * the memory latency.
+ */
+ std::deque<DeferredPacket> packetQueue;
- /// Bandwidth in ticks per byte
+ /**
+ * Bandwidth in ticks per byte. The regulation affects the
+ * acceptance rate of requests and the queueing takes place after
+ * the regulation.
+ */
const double bandwidth;
/**
@@ -111,6 +147,12 @@ class SimpleMemory : public AbstractMemory
bool retryReq;
/**
+ * Remember if we failed to send a response and are awaiting a
+ * retry. This is only used as a check.
+ */
+ bool retryResp;
+
+ /**
* Release the memory after being busy and send a retry if a
* request was rejected in the meanwhile.
*/
@@ -118,29 +160,52 @@ class SimpleMemory : public AbstractMemory
EventWrapper<SimpleMemory, &SimpleMemory::release> releaseEvent;
+ /**
+ * Dequeue a packet from our internal packet queue and move it to
+ * the port where it will be sent as soon as possible.
+ */
+ void dequeue();
+
+ EventWrapper<SimpleMemory, &SimpleMemory::dequeue> dequeueEvent;
+
+ /**
+ * Detemine the latency.
+ *
+ * @return the latency seen by the current packet
+ */
+ Tick getLatency() const;
+
/** @todo this is a temporary workaround until the 4-phase code is
* committed. upstream caches needs this packet until true is returned, so
* hold onto it for deletion until a subsequent call
*/
std::vector<PacketPtr> pendingDelete;
+ /**
+ * If we need to drain, keep the drain manager around until we're
+ * done here.
+ */
+ DrainManager *drainManager;
+
public:
SimpleMemory(const SimpleMemoryParams *p);
- virtual ~SimpleMemory() { }
unsigned int drain(DrainManager *dm);
- virtual BaseSlavePort& getSlavePort(const std::string& if_name,
- PortID idx = InvalidPortID);
- virtual void init();
+ BaseSlavePort& getSlavePort(const std::string& if_name,
+ PortID idx = InvalidPortID);
+ void init();
protected:
- Tick doAtomicAccess(PacketPtr pkt);
- void doFunctionalAccess(PacketPtr pkt);
+ Tick recvAtomic(PacketPtr pkt);
+
+ void recvFunctional(PacketPtr pkt);
+
bool recvTimingReq(PacketPtr pkt);
- Tick calculateLatency(PacketPtr pkt);
+
+ void recvRetry();
};