summaryrefslogtreecommitdiff
path: root/src/mem/simple_mem.hh
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-08-19 03:52:25 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-08-19 03:52:25 -0400
commit2a675aecb904143327befde70704d87c85fe7ea5 (patch)
tree7d08e554bcbf6959316a7174e46a755009026894 /src/mem/simple_mem.hh
parent9b2effd9e2d30c5e2a72bfe78214cd88689d89d9 (diff)
downloadgem5-2a675aecb904143327befde70704d87c85fe7ea5.tar.xz
mem: Add an internal packet queue in SimpleMemory
This patch adds a packet queue in SimpleMemory to avoid using the packet queue in the port (and thus have no involvement in the flow control). The port queue was bound to 100 packets, and as the SimpleMemory is modelling both a controller and an actual RAM, it potentially has a large number of packets in flight. There is currently no limit on the number of packets in the memory controller, but this could easily be added in a follow-on patch. As a result of the added internal storage, the functional access and draining is updated. Some minor cleaning up and renaming has also been done. The memtest regression changes as a result of this patch and the stats will be updated.
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();
};